mmdevapi/tests: Add tests for volume control interfaces.
[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_SYSMENU | WS_POPUP , 0, 0, 640, 480, 0, 0, 0, 0);
47     ShowWindow(ret, SW_SHOW);
48     return ret;
49 }
50
51 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
52 {
53     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
54     c1 >>= 8; c2 >>= 8;
55     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56     c1 >>= 8; c2 >>= 8;
57     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
58     c1 >>= 8; c2 >>= 8;
59     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
60     return TRUE;
61 }
62
63 /* Locks a given surface and returns the color at (x,y).  It's the caller's
64  * responsibility to only pass in lockable surfaces and valid x,y coordinates */
65 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
66 {
67     DWORD color;
68     HRESULT hr;
69     D3DSURFACE_DESC desc;
70     RECT rectToLock = {x, y, x+1, y+1};
71     D3DLOCKED_RECT lockedRect;
72
73     hr = IDirect3DSurface9_GetDesc(surface, &desc);
74     if(FAILED(hr))  /* This is not a test */
75     {
76         trace("Can't get the surface description, hr=%08x\n", hr);
77         return 0xdeadbeef;
78     }
79
80     hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
81     if(FAILED(hr))  /* This is not a test */
82     {
83         trace("Can't lock the surface, hr=%08x\n", hr);
84         return 0xdeadbeef;
85     }
86     switch(desc.Format) {
87         case D3DFMT_A8R8G8B8:
88         {
89             color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
90             break;
91         }
92         default:
93             trace("Error: unknown surface format: %d\n", desc.Format);
94             color = 0xdeadbeef;
95             break;
96     }
97     hr = IDirect3DSurface9_UnlockRect(surface);
98     if(FAILED(hr))
99     {
100         trace("Can't unlock the surface, hr=%08x\n", hr);
101     }
102     return color;
103 }
104
105 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
106 {
107     DWORD ret;
108     IDirect3DSurface9 *surf = NULL, *target = NULL;
109     HRESULT hr;
110     D3DLOCKED_RECT lockedRect;
111     RECT rectToLock = {x, y, x+1, y+1};
112
113     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480,
114             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
115     if (FAILED(hr) || !surf)
116     {
117         trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
118         return 0xdeadbeef;
119     }
120
121     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
122     if(FAILED(hr))
123     {
124         trace("Can't get the render target, hr=%08x\n", hr);
125         ret = 0xdeadbeed;
126         goto out;
127     }
128
129     hr = IDirect3DDevice9_GetRenderTargetData(device, target, surf);
130     if (FAILED(hr))
131     {
132         trace("Can't read the render target data, hr=%08x\n", hr);
133         ret = 0xdeadbeec;
134         goto out;
135     }
136
137     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
138     if(FAILED(hr))
139     {
140         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
141         ret = 0xdeadbeeb;
142         goto out;
143     }
144
145     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
146      * really important for these tests
147      */
148     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
149     hr = IDirect3DSurface9_UnlockRect(surf);
150     if(FAILED(hr))
151     {
152         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
153     }
154
155 out:
156     if(target) IDirect3DSurface9_Release(target);
157     if(surf) IDirect3DSurface9_Release(surf);
158     return ret;
159 }
160
161 static IDirect3DDevice9 *init_d3d9(void)
162 {
163     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
164     IDirect3D9 *d3d9_ptr = 0;
165     IDirect3DDevice9 *device_ptr = 0;
166     D3DPRESENT_PARAMETERS present_parameters;
167     HRESULT hr;
168     D3DADAPTER_IDENTIFIER9 identifier;
169
170     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
171     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
172     if (!d3d9_create) return NULL;
173
174     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
175     if (!d3d9_ptr)
176     {
177         skip("could not create D3D9\n");
178         return NULL;
179     }
180
181     ZeroMemory(&present_parameters, sizeof(present_parameters));
182     present_parameters.Windowed = TRUE;
183     present_parameters.hDeviceWindow = create_window();
184     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
185     present_parameters.BackBufferWidth = 640;
186     present_parameters.BackBufferHeight = 480;
187     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
188     present_parameters.EnableAutoDepthStencil = TRUE;
189     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
190
191     memset(&identifier, 0, sizeof(identifier));
192     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
193     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
194     trace("Driver string: \"%s\"\n", identifier.Driver);
195     trace("Description string: \"%s\"\n", identifier.Description);
196     ok(identifier.Description[0] != '\0', "Empty driver description\n");
197     trace("Device name string: \"%s\"\n", identifier.DeviceName);
198     ok(identifier.DeviceName[0]  != '\0', "Empty device name\n");
199     trace("Driver version %d.%d.%d.%d\n",
200           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
201           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
202
203     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
204     if(FAILED(hr)) {
205         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
206         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
207         if(FAILED(hr)) {
208             hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
209         }
210     }
211     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
212
213     return device_ptr;
214 }
215
216 struct vertex
217 {
218     float x, y, z;
219     DWORD diffuse;
220 };
221
222 struct tvertex
223 {
224     float x, y, z, rhw;
225     DWORD diffuse;
226 };
227
228 struct nvertex
229 {
230     float x, y, z;
231     float nx, ny, nz;
232     DWORD diffuse;
233 };
234
235 static void lighting_test(IDirect3DDevice9 *device)
236 {
237     HRESULT hr;
238     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
239     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
240     DWORD color;
241     D3DMATERIAL9 material, old_material;
242     DWORD cop, carg;
243
244     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
245                       0.0f, 1.0f, 0.0f, 0.0f,
246                       0.0f, 0.0f, 1.0f, 0.0f,
247                       0.0f, 0.0f, 0.0f, 1.0f };
248
249     struct vertex unlitquad[] =
250     {
251         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
252         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
253         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
254         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
255     };
256     struct vertex litquad[] =
257     {
258         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
259         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
260         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
261         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
262     };
263     struct nvertex unlitnquad[] =
264     {
265         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
266         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
267         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
268         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
269     };
270     struct nvertex litnquad[] =
271     {
272         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
273         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
274         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
275         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
276     };
277     WORD Indices[] = {0, 1, 2, 2, 3, 0};
278
279     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
280     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
281
282     /* Setup some states that may cause issues */
283     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
284     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
285     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
286     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
287     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
288     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
289     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
290     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
291     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
292     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
293     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
294     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
295     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
296     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
297     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
298     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
299     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
300     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
301     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
302     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
303     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
304     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
305     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
306     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
307
308     hr = IDirect3DDevice9_SetFVF(device, 0);
309     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
310
311     hr = IDirect3DDevice9_SetFVF(device, fvf);
312     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
313
314     hr = IDirect3DDevice9_BeginScene(device);
315     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
316     if(hr == D3D_OK)
317     {
318         /* No lights are defined... That means, lit vertices should be entirely black */
319         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
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, unlitquad, sizeof(unlitquad[0]));
323         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
324
325         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
326         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
327         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
328                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
329         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
330
331         hr = IDirect3DDevice9_SetFVF(device, nfvf);
332         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
333
334         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
335         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
336         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
337                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
338         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
339
340         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
341         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
342         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
343                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
344         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
345
346         IDirect3DDevice9_EndScene(device);
347         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
348     }
349
350     color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
351     ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
352     color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
353     ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
354     color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
355     ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
356     color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
357     ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
358
359     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
360
361     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
362     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
363     memset(&material, 0, sizeof(material));
364     material.Diffuse.r = 0.0;
365     material.Diffuse.g = 0.0;
366     material.Diffuse.b = 0.0;
367     material.Diffuse.a = 1.0;
368     material.Ambient.r = 0.0;
369     material.Ambient.g = 0.0;
370     material.Ambient.b = 0.0;
371     material.Ambient.a = 0.0;
372     material.Specular.r = 0.0;
373     material.Specular.g = 0.0;
374     material.Specular.b = 0.0;
375     material.Specular.a = 0.0;
376     material.Emissive.r = 0.0;
377     material.Emissive.g = 0.0;
378     material.Emissive.b = 0.0;
379     material.Emissive.a = 0.0;
380     material.Power = 0.0;
381     IDirect3DDevice9_SetMaterial(device, &material);
382     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
383
384     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
385     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
386     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
387     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
388
389     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
390     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
391     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
392     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
393     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
394     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
395     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
396     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
397
398     hr = IDirect3DDevice9_BeginScene(device);
399     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
400     if(SUCCEEDED(hr)) {
401         struct vertex lighting_test[] = {
402             {-1.0,   -1.0,   0.1,    0x8000ff00},
403             { 1.0,   -1.0,   0.1,    0x80000000},
404             {-1.0,    1.0,   0.1,    0x8000ff00},
405             { 1.0,    1.0,   0.1,    0x80000000}
406         };
407         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
408         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
409         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
410         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
411
412         hr = IDirect3DDevice9_EndScene(device);
413         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
414     }
415
416     color = getPixelColor(device, 320, 240);
417     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
418     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
419
420     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
421     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
422     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
423     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
424     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
425     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
426     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
427     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
428     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
429     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
430     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
431     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
432 }
433
434 static void clear_test(IDirect3DDevice9 *device)
435 {
436     /* Tests the correctness of clearing parameters */
437     HRESULT hr;
438     D3DRECT rect[2];
439     D3DRECT rect_negneg;
440     DWORD color;
441     D3DVIEWPORT9 old_vp, vp;
442     RECT scissor;
443     DWORD oldColorWrite;
444     BOOL invalid_clear_failed = FALSE;
445
446     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
447     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
448
449     /* Positive x, negative y */
450     rect[0].x1 = 0;
451     rect[0].y1 = 480;
452     rect[0].x2 = 320;
453     rect[0].y2 = 240;
454
455     /* Positive x, positive y */
456     rect[1].x1 = 0;
457     rect[1].y1 = 0;
458     rect[1].x2 = 320;
459     rect[1].y2 = 240;
460     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
461      * returns D3D_OK, but ignores the rectangle silently
462      */
463     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
464     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
465     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
466
467     /* negative x, negative y */
468     rect_negneg.x1 = 640;
469     rect_negneg.y1 = 240;
470     rect_negneg.x2 = 320;
471     rect_negneg.y2 = 0;
472     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
473     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
474     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
475
476     color = getPixelColor(device, 160, 360); /* lower left quad */
477     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
478     color = getPixelColor(device, 160, 120); /* upper left quad */
479     if(invalid_clear_failed) {
480         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
481         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
482     } else {
483         /* If the negative rectangle was dropped silently, the correct ones are cleared */
484         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
485     }
486     color = getPixelColor(device, 480, 360); /* lower right quad  */
487     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
488     color = getPixelColor(device, 480, 120); /* upper right quad */
489     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
490
491     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
492
493     /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
494      * clear the red quad in the top left part of the render target. For some reason it
495      * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
496      * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
497      * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
498      * pick some obvious value
499      */
500     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
501     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
502
503     /* Test how the viewport affects clears */
504     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
505     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
506     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
507     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
508
509     vp.X = 160;
510     vp.Y = 120;
511     vp.Width = 160;
512     vp.Height = 120;
513     vp.MinZ = 0.0;
514     vp.MaxZ = 1.0;
515     hr = IDirect3DDevice9_SetViewport(device, &vp);
516     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
517     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
518     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
519
520     vp.X = 320;
521     vp.Y = 240;
522     vp.Width = 320;
523     vp.Height = 240;
524     vp.MinZ = 0.0;
525     vp.MaxZ = 1.0;
526     hr = IDirect3DDevice9_SetViewport(device, &vp);
527     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
528     rect[0].x1 = 160;
529     rect[0].y1 = 120;
530     rect[0].x2 = 480;
531     rect[0].y2 = 360;
532     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
533     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
534
535     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
536     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
537
538     color = getPixelColor(device, 158, 118);
539     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
540     color = getPixelColor(device, 162, 118);
541     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
542     color = getPixelColor(device, 158, 122);
543     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
544     color = getPixelColor(device, 162, 122);
545     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
546
547     color = getPixelColor(device, 318, 238);
548     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
549     color = getPixelColor(device, 322, 238);
550     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
551     color = getPixelColor(device, 318, 242);
552     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
553     color = getPixelColor(device, 322, 242);
554     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
555
556     color = getPixelColor(device, 478, 358);
557     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
558     color = getPixelColor(device, 482, 358);
559     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
560     color = getPixelColor(device, 478, 362);
561     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
562     color = getPixelColor(device, 482, 362);
563     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
564
565     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
566
567     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
568     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
569
570     scissor.left = 160;
571     scissor.right = 480;
572     scissor.top = 120;
573     scissor.bottom = 360;
574     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
575     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
576     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
577     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
578
579     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
580     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
581     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
582     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
583
584     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
585     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
586
587     color = getPixelColor(device, 158, 118);
588     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
589     color = getPixelColor(device, 162, 118);
590     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
591     color = getPixelColor(device, 158, 122);
592     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
593     color = getPixelColor(device, 162, 122);
594     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
595
596     color = getPixelColor(device, 158, 358);
597     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
598     color = getPixelColor(device, 162, 358);
599     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
600     color = getPixelColor(device, 158, 358);
601     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
602     color = getPixelColor(device, 162, 362);
603     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
604
605     color = getPixelColor(device, 478, 118);
606     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
607     color = getPixelColor(device, 478, 122);
608     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
609     color = getPixelColor(device, 482, 122);
610     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
611     color = getPixelColor(device, 482, 358);
612     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
613
614     color = getPixelColor(device, 478, 358);
615     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
616     color = getPixelColor(device, 478, 362);
617     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
618     color = getPixelColor(device, 482, 358);
619     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
620     color = getPixelColor(device, 482, 362);
621     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
622
623     color = getPixelColor(device, 318, 238);
624     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
625     color = getPixelColor(device, 318, 242);
626     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
627     color = getPixelColor(device, 322, 238);
628     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
629     color = getPixelColor(device, 322, 242);
630     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
631
632     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
633
634     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
635     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
636     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
637     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
638
639     /* Same nvidia windows driver trouble with white clears as earlier in the same test */
640     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
641     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
642
643     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
644     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
645
646     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
647     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
648
649     /* Colorwriteenable does not affect the clear */
650     color = getPixelColor(device, 320, 240);
651     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
652
653     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
654 }
655
656 static void color_fill_test(IDirect3DDevice9 *device)
657 {
658     HRESULT hr;
659     IDirect3DSurface9 *backbuffer = NULL;
660     IDirect3DSurface9 *rt_surface = NULL;
661     IDirect3DSurface9 *offscreen_surface = NULL;
662     DWORD fill_color, color;
663
664     /* Test ColorFill on a the backbuffer (should pass) */
665     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
666     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
667     if(backbuffer)
668     {
669         fill_color = 0x112233;
670         hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
671         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
672
673         color = getPixelColor(device, 0, 0);
674         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
675
676         IDirect3DSurface9_Release(backbuffer);
677     }
678
679     /* Test ColorFill on a render target surface (should pass) */
680     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
681     ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
682     if(rt_surface)
683     {
684         fill_color = 0x445566;
685         hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
686         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
687
688         color = getPixelColorFromSurface(rt_surface, 0, 0);
689         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
690
691         IDirect3DSurface9_Release(rt_surface);
692     }
693
694     /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
695     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
696             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
697     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
698     if(offscreen_surface)
699     {
700         fill_color = 0x778899;
701         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
702         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
703
704         color = getPixelColorFromSurface(offscreen_surface, 0, 0);
705         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
706
707         IDirect3DSurface9_Release(offscreen_surface);
708     }
709
710     /* Try ColorFill on a offscreen surface in sysmem (should fail) */
711     offscreen_surface = NULL;
712     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
713             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
714     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
715     if(offscreen_surface)
716     {
717         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
718         ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
719
720         IDirect3DSurface9_Release(offscreen_surface);
721     }
722 }
723
724 typedef struct {
725     float in[4];
726     DWORD out;
727 } test_data_t;
728
729 /*
730  *  c7      mova    ARGB            mov     ARGB
731  * -2.4     -2      0x00ffff00      -3      0x00ff0000
732  * -1.6     -2      0x00ffff00      -2      0x00ffff00
733  * -0.4      0      0x0000ffff      -1      0x0000ff00
734  *  0.4      0      0x0000ffff       0      0x0000ffff
735  *  1.6      2      0x00ff00ff       1      0x000000ff
736  *  2.4      2      0x00ff00ff       2      0x00ff00ff
737  */
738 static void test_mova(IDirect3DDevice9 *device)
739 {
740     static const DWORD mova_test[] = {
741         0xfffe0200,                                                             /* vs_2_0                       */
742         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
743         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
744         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
745         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
746         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
747         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
748         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
749         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
750         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
751         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
752         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
753         0x0000ffff                                                              /* END                          */
754     };
755     static const DWORD mov_test[] = {
756         0xfffe0101,                                                             /* vs_1_1                       */
757         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
758         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
759         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
760         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
761         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
762         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
763         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
764         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
765         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
766         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
767         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
768         0x0000ffff                                                              /* END                          */
769     };
770
771     static const test_data_t test_data[2][6] = {
772         {
773             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
774             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
775             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
776             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
777             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
778             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
779         },
780         {
781             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
782             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
783             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
784             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
785             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
786             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
787         }
788     };
789
790     static const float quad[][3] = {
791         {-1.0f, -1.0f, 0.0f},
792         {-1.0f,  1.0f, 0.0f},
793         { 1.0f, -1.0f, 0.0f},
794         { 1.0f,  1.0f, 0.0f},
795     };
796
797     static const D3DVERTEXELEMENT9 decl_elements[] = {
798         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
799         D3DDECL_END()
800     };
801
802     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
803     IDirect3DVertexShader9 *mova_shader = NULL;
804     IDirect3DVertexShader9 *mov_shader = NULL;
805     HRESULT hr;
806     UINT i, j;
807
808     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
809     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
810     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
811     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
812     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
813     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
814     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
815     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
816
817     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
818     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
819     for(j = 0; j < 2; ++j)
820     {
821         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
822         {
823             DWORD color;
824
825             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
826             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
827
828             hr = IDirect3DDevice9_BeginScene(device);
829             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
830
831             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
832             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
833
834             hr = IDirect3DDevice9_EndScene(device);
835             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
836
837             color = getPixelColor(device, 320, 240);
838             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
839                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
840
841             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
842             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
843
844             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
845             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
846         }
847         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
848         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
849     }
850
851     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
852     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
853
854     IDirect3DVertexDeclaration9_Release(vertex_declaration);
855     IDirect3DVertexShader9_Release(mova_shader);
856     IDirect3DVertexShader9_Release(mov_shader);
857 }
858
859 struct sVertex {
860     float x, y, z;
861     DWORD diffuse;
862     DWORD specular;
863 };
864
865 struct sVertexT {
866     float x, y, z, rhw;
867     DWORD diffuse;
868     DWORD specular;
869 };
870
871 static void fog_test(IDirect3DDevice9 *device)
872 {
873     HRESULT hr;
874     D3DCOLOR color;
875     float start = 0.0f, end = 1.0f;
876     D3DCAPS9 caps;
877     int i;
878
879     /* Gets full z based fog with linear fog, no fog with specular color */
880     struct sVertex unstransformed_1[] = {
881         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
882         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
883         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
884         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
885     };
886     /* Ok, I am too lazy to deal with transform matrices */
887     struct sVertex unstransformed_2[] = {
888         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
889         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
890         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
891         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
892     };
893     /* Untransformed ones. Give them a different diffuse color to make the test look
894      * nicer. It also makes making sure that they are drawn correctly easier.
895      */
896     struct sVertexT transformed_1[] = {
897         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
898         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
899         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
900         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
901     };
902     struct sVertexT transformed_2[] = {
903         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
904         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
905         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
906         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
907     };
908     struct vertex rev_fog_quads[] = {
909        {-1.0,   -1.0,   0.1,    0x000000ff},
910        {-1.0,    0.0,   0.1,    0x000000ff},
911        { 0.0,    0.0,   0.1,    0x000000ff},
912        { 0.0,   -1.0,   0.1,    0x000000ff},
913
914        { 0.0,   -1.0,   0.9,    0x000000ff},
915        { 0.0,    0.0,   0.9,    0x000000ff},
916        { 1.0,    0.0,   0.9,    0x000000ff},
917        { 1.0,   -1.0,   0.9,    0x000000ff},
918
919        { 0.0,    0.0,   0.4,    0x000000ff},
920        { 0.0,    1.0,   0.4,    0x000000ff},
921        { 1.0,    1.0,   0.4,    0x000000ff},
922        { 1.0,    0.0,   0.4,    0x000000ff},
923
924        {-1.0,    0.0,   0.7,    0x000000ff},
925        {-1.0,    1.0,   0.7,    0x000000ff},
926        { 0.0,    1.0,   0.7,    0x000000ff},
927        { 0.0,    0.0,   0.7,    0x000000ff},
928     };
929     WORD Indices[] = {0, 1, 2, 2, 3, 0};
930
931     memset(&caps, 0, sizeof(caps));
932     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
933     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
934     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
935     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
936
937     /* Setup initial states: No lighting, fog on, fog color */
938     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
939     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
940     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
941     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
942     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
943     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
944
945     /* First test: Both table fog and vertex fog off */
946     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
947     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
948     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
949     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
950
951     /* Start = 0, end = 1. Should be default, but set them */
952     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
953     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
954     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
955     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
956
957     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
958     {
959         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
960         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
961         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
962         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
963                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
964                                                      sizeof(unstransformed_1[0]));
965         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
966
967         /* That makes it use the Z value */
968         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
969         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
970         /* Untransformed, vertex fog != none (or table fog != none):
971          * Use the Z value as input into the equation
972          */
973         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
974                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
975                                                      sizeof(unstransformed_1[0]));
976         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
977
978         /* transformed verts */
979         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
980         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
981         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
982         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
983                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
984                                                      sizeof(transformed_1[0]));
985         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
986
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         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
990          * equation
991          */
992         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
993                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
994                                                      sizeof(transformed_2[0]));
995         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
996
997         hr = IDirect3DDevice9_EndScene(device);
998         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
999     }
1000     else
1001     {
1002         ok(FALSE, "BeginScene failed\n");
1003     }
1004
1005     color = getPixelColor(device, 160, 360);
1006     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1007     color = getPixelColor(device, 160, 120);
1008     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1009     color = getPixelColor(device, 480, 120);
1010     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1011     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1012     {
1013         color = getPixelColor(device, 480, 360);
1014         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1015     }
1016     else
1017     {
1018         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1019          * The settings above result in no fogging with vertex fog
1020          */
1021         color = getPixelColor(device, 480, 120);
1022         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1023         trace("Info: Table fog not supported by this device\n");
1024     }
1025     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1026
1027     /* Now test the special case fogstart == fogend */
1028     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1029     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1030
1031     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1032     {
1033         start = 512;
1034         end = 512;
1035         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1036         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1037         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1038         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1039
1040         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1041         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1042         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1043         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1044         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1045         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1046
1047         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1048          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1049          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1050          * The third transformed quad remains unfogged because the fogcoords are read from the specular
1051          * color and has fixed fogstart and fogend.
1052          */
1053         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1054                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
1055                 sizeof(unstransformed_1[0]));
1056         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1057         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1058                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
1059                 sizeof(unstransformed_1[0]));
1060         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1061
1062         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1063         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1064         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1065         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1066                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1067                 sizeof(transformed_1[0]));
1068         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1069
1070         hr = IDirect3DDevice9_EndScene(device);
1071         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1072     }
1073     else
1074     {
1075         ok(FALSE, "BeginScene failed\n");
1076     }
1077     color = getPixelColor(device, 160, 360);
1078     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1079     color = getPixelColor(device, 160, 120);
1080     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1081     color = getPixelColor(device, 480, 120);
1082     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1083     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1084
1085     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1086      * but without shaders it seems to work everywhere
1087      */
1088     end = 0.2;
1089     start = 0.8;
1090     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1091     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1092     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1093     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1094     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1095     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1096
1097     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1098      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1099      * so skip this for now
1100      */
1101     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1102         const char *mode = (i ? "table" : "vertex");
1103         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1104         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1105         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1106         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1107         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1108         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1109         hr = IDirect3DDevice9_BeginScene(device);
1110         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1111         if(SUCCEEDED(hr)) {
1112             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1113                                 4,  5,  6,  6,  7, 4,
1114                                 8,  9, 10, 10, 11, 8,
1115                             12, 13, 14, 14, 15, 12};
1116
1117             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1118                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1119                     sizeof(rev_fog_quads[0]));
1120             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1121
1122             hr = IDirect3DDevice9_EndScene(device);
1123             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1124         }
1125         color = getPixelColor(device, 160, 360);
1126         ok(color_match(color, 0x0000ff00, 1),
1127                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1128
1129         color = getPixelColor(device, 160, 120);
1130         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1131                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1132
1133         color = getPixelColor(device, 480, 120);
1134         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1135                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1136
1137         color = getPixelColor(device, 480, 360);
1138         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1139
1140         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1141
1142         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1143             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1144             break;
1145         }
1146     }
1147     /* Turn off the fog master switch to avoid confusing other tests */
1148     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1149     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1150     start = 0.0;
1151     end = 1.0;
1152     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1153     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1154     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1155     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1156     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1157     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1158     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1159     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1160 }
1161
1162 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1163  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1164  * regardless of the actual addressing mode set. The way this test works is
1165  * that we sample in one of the corners of the cubemap with filtering enabled,
1166  * and check the interpolated color. There are essentially two reasonable
1167  * things an implementation can do: Either pick one of the faces and
1168  * interpolate the edge texel with itself (i.e., clamp within the face), or
1169  * interpolate between the edge texels of the three involved faces. It should
1170  * never involve the border color or the other side (texcoord wrapping) of a
1171  * face in the interpolation. */
1172 static void test_cube_wrap(IDirect3DDevice9 *device)
1173 {
1174     static const float quad[][6] = {
1175         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1176         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1177         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1178         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1179     };
1180
1181     static const D3DVERTEXELEMENT9 decl_elements[] = {
1182         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1183         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1184         D3DDECL_END()
1185     };
1186
1187     static const struct {
1188         D3DTEXTUREADDRESS mode;
1189         const char *name;
1190     } address_modes[] = {
1191         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1192         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1193         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1194         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1195         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1196     };
1197
1198     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1199     IDirect3DCubeTexture9 *texture = NULL;
1200     IDirect3DSurface9 *surface = NULL;
1201     IDirect3DSurface9 *face_surface;
1202     D3DLOCKED_RECT locked_rect;
1203     HRESULT hr;
1204     UINT x;
1205     INT y, face;
1206
1207     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1208     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1209     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1210     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1211
1212     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1213             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1214     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1215
1216     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1217             D3DPOOL_DEFAULT, &texture, NULL);
1218     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1219
1220     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1221     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1222
1223     for (y = 0; y < 128; ++y)
1224     {
1225         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1226         for (x = 0; x < 64; ++x)
1227         {
1228             *ptr++ = 0xff0000ff;
1229         }
1230         for (x = 64; x < 128; ++x)
1231         {
1232             *ptr++ = 0xffff0000;
1233         }
1234     }
1235
1236     hr = IDirect3DSurface9_UnlockRect(surface);
1237     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1238
1239     hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1240     ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1241
1242     hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1243     ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1244
1245     IDirect3DSurface9_Release(face_surface);
1246
1247     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1248     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1249
1250     for (y = 0; y < 128; ++y)
1251     {
1252         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1253         for (x = 0; x < 64; ++x)
1254         {
1255             *ptr++ = 0xffff0000;
1256         }
1257         for (x = 64; x < 128; ++x)
1258         {
1259             *ptr++ = 0xff0000ff;
1260         }
1261     }
1262
1263     hr = IDirect3DSurface9_UnlockRect(surface);
1264     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1265
1266     /* Create cube faces */
1267     for (face = 1; face < 6; ++face)
1268     {
1269         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1270         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1271
1272         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1273         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1274
1275         IDirect3DSurface9_Release(face_surface);
1276     }
1277
1278     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1279     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1280
1281     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1282     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1283     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1284     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1285     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1286     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1287
1288     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1289     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1290
1291     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1292     {
1293         DWORD color;
1294
1295         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1296         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1297         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1298         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1299
1300         hr = IDirect3DDevice9_BeginScene(device);
1301         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1302
1303         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1304         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1305
1306         hr = IDirect3DDevice9_EndScene(device);
1307         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1308
1309         color = getPixelColor(device, 320, 240);
1310         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1311                 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1312                 color, address_modes[x].name);
1313
1314         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1315         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1316
1317         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1318         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1319     }
1320
1321     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1322     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1323
1324     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1325     IDirect3DCubeTexture9_Release(texture);
1326     IDirect3DSurface9_Release(surface);
1327 }
1328
1329 static void offscreen_test(IDirect3DDevice9 *device)
1330 {
1331     HRESULT hr;
1332     IDirect3DTexture9 *offscreenTexture = NULL;
1333     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1334     DWORD color;
1335
1336     static const float quad[][5] = {
1337         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1338         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1339         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1340         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1341     };
1342
1343     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1344     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1345
1346     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1347     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1348     if(!offscreenTexture) {
1349         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1350         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1351         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1352         if(!offscreenTexture) {
1353             skip("Cannot create an offscreen render target\n");
1354             goto out;
1355         }
1356     }
1357
1358     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1359     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1360     if(!backbuffer) {
1361         goto out;
1362     }
1363
1364     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1365     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1366     if(!offscreen) {
1367         goto out;
1368     }
1369
1370     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1371     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1372
1373     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1374     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1375     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1376     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1377     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1378     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1379     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1380     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1381     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1382     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1383
1384     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1385         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1386         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1387         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1388         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1389
1390         /* Draw without textures - Should result in a white quad */
1391         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1392         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1393
1394         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1395         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1396         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1397         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1398
1399         /* This time with the texture */
1400         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1401         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1402
1403         IDirect3DDevice9_EndScene(device);
1404     }
1405
1406     /* Center quad - should be white */
1407     color = getPixelColor(device, 320, 240);
1408     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1409     /* Some quad in the cleared part of the texture */
1410     color = getPixelColor(device, 170, 240);
1411     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1412     /* Part of the originally cleared back buffer */
1413     color = getPixelColor(device, 10, 10);
1414     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1415     if(0) {
1416         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1417          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1418          * the offscreen rendering mode this test would succeed or fail
1419          */
1420         color = getPixelColor(device, 10, 470);
1421         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1422     }
1423
1424     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1425
1426 out:
1427     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1428     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1429
1430     /* restore things */
1431     if(backbuffer) {
1432         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1433         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1434         IDirect3DSurface9_Release(backbuffer);
1435     }
1436     if(offscreenTexture) {
1437         IDirect3DTexture9_Release(offscreenTexture);
1438     }
1439     if(offscreen) {
1440         IDirect3DSurface9_Release(offscreen);
1441     }
1442 }
1443
1444 /* This test tests fog in combination with shaders.
1445  * What's tested: linear fog (vertex and table) with pixel shader
1446  *                linear table fog with non foggy vertex shader
1447  *                vertex fog with foggy vertex shader, non-linear
1448  *                fog with shader, non-linear fog with foggy shader,
1449  *                linear table fog with foggy shader
1450  */
1451 static void fog_with_shader_test(IDirect3DDevice9 *device)
1452 {
1453     HRESULT hr;
1454     DWORD color;
1455     union {
1456         float f;
1457         DWORD i;
1458     } start, end;
1459     unsigned int i, j;
1460
1461     /* basic vertex shader without fog computation ("non foggy") */
1462     static const DWORD vertex_shader_code1[] = {
1463         0xfffe0101,                                                             /* vs_1_1                       */
1464         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1465         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1466         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1467         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1468         0x0000ffff
1469     };
1470     /* basic vertex shader with reversed fog computation ("foggy") */
1471     static const DWORD vertex_shader_code2[] = {
1472         0xfffe0101,                                                             /* vs_1_1                        */
1473         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1474         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1475         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1476         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1477         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1478         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1479         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1480         0x0000ffff
1481     };
1482     /* basic pixel shader */
1483     static const DWORD pixel_shader_code[] = {
1484         0xffff0101,                                                             /* ps_1_1     */
1485         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1486         0x0000ffff
1487     };
1488
1489     static struct vertex quad[] = {
1490         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1491         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1492         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1493         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1494     };
1495
1496     static const D3DVERTEXELEMENT9 decl_elements[] = {
1497         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1498         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1499         D3DDECL_END()
1500     };
1501
1502     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1503     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1504     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1505
1506     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1507     static const struct test_data_t {
1508         int vshader;
1509         int pshader;
1510         D3DFOGMODE vfog;
1511         D3DFOGMODE tfog;
1512         unsigned int color[11];
1513     } test_data[] = {
1514         /* only pixel shader: */
1515         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1516         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1517         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1518         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1519         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1520         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1521         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1522         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1523         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1524         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1525         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1526         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1527         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1528         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1529         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1530
1531         /* vertex shader */
1532         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1533         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1534          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1535         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1536         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1537         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1538         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1539         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1540         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1541
1542         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1543         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1544         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1545         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1546         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1547         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1548
1549         /* vertex shader and pixel shader */
1550         /* The next 4 tests would read the fog coord output, but it isn't available.
1551          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1552          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1553          * These tests should be disabled if some other hardware behaves differently
1554          */
1555         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1556         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1557         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1558         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1559         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1560         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1561         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1562         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1563         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1564         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1565         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1566         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1567
1568         /* These use the Z coordinate with linear table fog */
1569         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1570         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1571         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1572         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1573         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1574         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1575         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1576         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1577         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1578         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1579         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1580         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1581
1582         /* Non-linear table fog without fog coord */
1583         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1584         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1585         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1586         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1587         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1588         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1589
1590 #if 0  /* FIXME: these fail on GeForce 8500 */
1591         /* foggy vertex shader */
1592         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1593         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1594          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1595         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1596         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1597          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1598         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1599         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1600          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1601         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1602         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1603          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1604 #endif
1605
1606         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1607          * all using the fixed fog-coord linear fog
1608          */
1609         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1610         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1611          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1612         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1613         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1614          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1615         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1616         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1617          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1618         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1619         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1620          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1621
1622         /* These use table fog. Here the shader-provided fog coordinate is
1623          * ignored and the z coordinate used instead
1624          */
1625         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1626         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1627         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1628         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1629         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1630         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1631         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1632         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1633         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1634     };
1635
1636     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1637     start.f=0.1f;
1638     end.f=0.9f;
1639
1640     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1641     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1642     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1643     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1644     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1645     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1646     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1647     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1648
1649     /* Setup initial states: No lighting, fog on, fog color */
1650     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1651     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1652     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1653     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1654     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1655     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1656     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1657     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1658
1659     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1660     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1661     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1662     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1663
1664     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1665     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1666     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1667     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1668     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1669
1670     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1671     {
1672         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1673         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1674         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1675         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1676         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1677         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1678         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1679         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1680
1681         for(j=0; j < 11; j++)
1682         {
1683             /* Don't use the whole zrange to prevent rounding errors */
1684             quad[0].z = 0.001f + (float)j / 10.02f;
1685             quad[1].z = 0.001f + (float)j / 10.02f;
1686             quad[2].z = 0.001f + (float)j / 10.02f;
1687             quad[3].z = 0.001f + (float)j / 10.02f;
1688
1689             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1690             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1691
1692             hr = IDirect3DDevice9_BeginScene(device);
1693             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1694
1695             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1696             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1697
1698             hr = IDirect3DDevice9_EndScene(device);
1699             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1700
1701             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1702             color = getPixelColor(device, 128, 240);
1703             ok(color_match(color, test_data[i].color[j], 13),
1704                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1705                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1706
1707             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1708         }
1709     }
1710
1711     /* reset states */
1712     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1713     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1714     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1715     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1716     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1717     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1718     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1719     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1720
1721     IDirect3DVertexShader9_Release(vertex_shader[1]);
1722     IDirect3DVertexShader9_Release(vertex_shader[2]);
1723     IDirect3DPixelShader9_Release(pixel_shader[1]);
1724     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1725 }
1726
1727 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1728     unsigned int i, x, y;
1729     HRESULT hr;
1730     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1731     D3DLOCKED_RECT locked_rect;
1732
1733     /* Generate the textures */
1734     for(i=0; i<2; i++)
1735     {
1736         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1737                                             D3DPOOL_MANAGED, &texture[i], NULL);
1738         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1739
1740         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1741         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1742         for (y = 0; y < 128; ++y)
1743         {
1744             if(i)
1745             { /* Set up black texture with 2x2 texel white spot in the middle */
1746                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1747                 for (x = 0; x < 128; ++x)
1748                 {
1749                     if(y>62 && y<66 && x>62 && x<66)
1750                         *ptr++ = 0xffffffff;
1751                     else
1752                         *ptr++ = 0xff000000;
1753                 }
1754             }
1755             else
1756             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1757                * (if multiplied with bumpenvmat)
1758               */
1759                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1760                 for (x = 0; x < 128; ++x)
1761                 {
1762                     if(abs(x-64)>abs(y-64))
1763                     {
1764                         if(x < 64)
1765                             *ptr++ = 0xc000;
1766                         else
1767                             *ptr++ = 0x4000;
1768                     }
1769                     else
1770                     {
1771                         if(y < 64)
1772                             *ptr++ = 0x0040;
1773                         else
1774                             *ptr++ = 0x00c0;
1775                     }
1776                 }
1777             }
1778         }
1779         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1780         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1781
1782         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1783         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1784
1785         /* Disable texture filtering */
1786         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1787         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1788         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1789         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1790
1791         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1792         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1793         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1794         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1795     }
1796 }
1797
1798 /* test the behavior of the texbem instruction
1799  * with normal 2D and projective 2D textures
1800  */
1801 static void texbem_test(IDirect3DDevice9 *device)
1802 {
1803     HRESULT hr;
1804     DWORD color;
1805     int i;
1806
1807     static const DWORD pixel_shader_code[] = {
1808         0xffff0101,                         /* ps_1_1*/
1809         0x00000042, 0xb00f0000,             /* tex t0*/
1810         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1811         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1812         0x0000ffff
1813     };
1814     static const DWORD double_texbem_code[] =  {
1815         0xffff0103,                                         /* ps_1_3           */
1816         0x00000042, 0xb00f0000,                             /* tex t0           */
1817         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1818         0x00000042, 0xb00f0002,                             /* tex t2           */
1819         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1820         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1821         0x0000ffff                                          /* end              */
1822     };
1823
1824
1825     static const float quad[][7] = {
1826         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1827         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1828         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1829         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1830     };
1831     static const float quad_proj[][9] = {
1832         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1833         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1834         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1835         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1836     };
1837
1838     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1839         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1840         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1841         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1842         D3DDECL_END()
1843     },{
1844         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1845         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1846         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1847         D3DDECL_END()
1848     } };
1849
1850     /* use asymmetric matrix to test loading */
1851     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1852
1853     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1854     IDirect3DPixelShader9       *pixel_shader       = NULL;
1855     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1856     D3DLOCKED_RECT locked_rect;
1857
1858     generate_bumpmap_textures(device);
1859
1860     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1861     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1862     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1863     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1864     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1865
1866     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1867     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1868
1869     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1870     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1871
1872     for(i=0; i<2; i++)
1873     {
1874         if(i)
1875         {
1876             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1877             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1878         }
1879
1880         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1881         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1882         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1883         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1884
1885         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1886         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1887         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1888         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1889
1890         hr = IDirect3DDevice9_BeginScene(device);
1891         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1892
1893         if(!i)
1894             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1895         else
1896             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1897         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1898
1899         hr = IDirect3DDevice9_EndScene(device);
1900         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1901
1902         color = getPixelColor(device, 320-32, 240);
1903         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1904         color = getPixelColor(device, 320+32, 240);
1905         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1906         color = getPixelColor(device, 320, 240-32);
1907         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1908         color = getPixelColor(device, 320, 240+32);
1909         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1910
1911         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1912         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1913
1914         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1915         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1916         IDirect3DPixelShader9_Release(pixel_shader);
1917
1918         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1919         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1920         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1921     }
1922
1923     /* clean up */
1924     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1925     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1926
1927     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1928     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1929
1930     for(i=0; i<2; i++)
1931     {
1932         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1933         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1934         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1935         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1936         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1937         IDirect3DTexture9_Release(texture);
1938     }
1939
1940     /* Test double texbem */
1941     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1942     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1943     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1944     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1945     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1946     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1947     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1948     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1949
1950     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1951     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1952     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1953     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1954
1955     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1956     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1957
1958     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1959     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1960     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1961     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1962     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1963     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1964
1965     {
1966         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1967 #define tex  0x00ff0000
1968 #define tex1 0x0000ff00
1969 #define origin 0x000000ff
1970         static const DWORD pixel_data[] = {
1971             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1972             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1973             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1974             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1975             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1976             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1977             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1978             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1979         };
1980 #undef tex1
1981 #undef tex2
1982 #undef origin
1983
1984         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1985         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1986         for(i = 0; i < 8; i++) {
1987             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1988         }
1989         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1990         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1991     }
1992
1993     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1994     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1995     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1996     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1997     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1998     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1999     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2000     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2001     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2002     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2003     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2004     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2005
2006     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
2007     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
2008     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2009     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2010     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2011     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2012     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2013     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2014     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2015     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2016
2017     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2018     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2019     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2020     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2021     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2022     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2023     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2024     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2025     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2026     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2027
2028     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2029     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2030     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2031     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2032     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2033     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2034     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2035     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2036     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2037     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2038     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2039     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2040     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2041     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2042     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2043     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2044
2045     hr = IDirect3DDevice9_BeginScene(device);
2046     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2047     if(SUCCEEDED(hr)) {
2048         static const float double_quad[] = {
2049             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2050              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2051             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2052              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2053         };
2054
2055         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2056         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2057         hr = IDirect3DDevice9_EndScene(device);
2058         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2059     }
2060     color = getPixelColor(device, 320, 240);
2061     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2062
2063     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2064     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2065     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2066     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2067     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2068     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2069     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2070     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2071     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2072     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2073
2074     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2075     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2076
2077     IDirect3DPixelShader9_Release(pixel_shader);
2078     IDirect3DTexture9_Release(texture);
2079     IDirect3DTexture9_Release(texture1);
2080     IDirect3DTexture9_Release(texture2);
2081 }
2082
2083 static void z_range_test(IDirect3DDevice9 *device)
2084 {
2085     const struct vertex quad[] =
2086     {
2087         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2088         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2089         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2090         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2091     };
2092     const struct vertex quad2[] =
2093     {
2094         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2095         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2096         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2097         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2098     };
2099
2100     const struct tvertex quad3[] =
2101     {
2102         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2103         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2104         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2105         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2106     };
2107     const struct tvertex quad4[] =
2108     {
2109         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2110         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2111         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2112         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2113     };
2114     HRESULT hr;
2115     DWORD color;
2116     IDirect3DVertexShader9 *shader;
2117     IDirect3DVertexDeclaration9 *decl;
2118     D3DCAPS9 caps;
2119     const DWORD shader_code[] = {
2120         0xfffe0101,                                     /* vs_1_1           */
2121         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2122         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2123         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2124         0x0000ffff                                      /* end              */
2125     };
2126     static const D3DVERTEXELEMENT9 decl_elements[] = {
2127         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2128         D3DDECL_END()
2129     };
2130     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2131      * then call Present. Then clear the color buffer to make sure it has some defined content
2132      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2133      * by the depth value.
2134      */
2135     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2136     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2137     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2138     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2139     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2140     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2141
2142     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2143     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2144     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2145     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2146     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2147     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2148     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2149     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2150     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2151     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2152
2153     hr = IDirect3DDevice9_BeginScene(device);
2154     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2155     if(hr == D3D_OK)
2156     {
2157         /* Test the untransformed vertex path */
2158         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2159         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2160         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2161         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2162         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2163         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2164
2165         /* Test the transformed vertex path */
2166         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2167         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2168
2169         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2170         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2171         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2172         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2173         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2174         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2175
2176         hr = IDirect3DDevice9_EndScene(device);
2177         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2178     }
2179
2180     /* Do not test the exact corner pixels, but go pretty close to them */
2181
2182     /* Clipped because z > 1.0 */
2183     color = getPixelColor(device, 28, 238);
2184     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2185     color = getPixelColor(device, 28, 241);
2186     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2187
2188     /* Not clipped, > z buffer clear value(0.75) */
2189     color = getPixelColor(device, 31, 238);
2190     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2191     color = getPixelColor(device, 31, 241);
2192     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2193     color = getPixelColor(device, 100, 238);
2194     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2195     color = getPixelColor(device, 100, 241);
2196     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2197
2198     /* Not clipped, < z buffer clear value */
2199     color = getPixelColor(device, 104, 238);
2200     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2201     color = getPixelColor(device, 104, 241);
2202     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2203     color = getPixelColor(device, 318, 238);
2204     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2205     color = getPixelColor(device, 318, 241);
2206     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2207
2208     /* Clipped because z < 0.0 */
2209     color = getPixelColor(device, 321, 238);
2210     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2211     color = getPixelColor(device, 321, 241);
2212     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2213
2214     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2215     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2216
2217     /* Test the shader path */
2218     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2219     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2220         skip("Vertex shaders not supported\n");
2221         goto out;
2222     }
2223     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2224     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2225     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2226     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2227
2228     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2229
2230     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2231     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2232     IDirect3DDevice9_SetVertexShader(device, shader);
2233     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2234
2235     hr = IDirect3DDevice9_BeginScene(device);
2236     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2237     if(hr == D3D_OK)
2238     {
2239         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2240         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2241         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2242         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2243         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2244         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2245         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2246         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2247         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2248         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2249
2250         hr = IDirect3DDevice9_EndScene(device);
2251         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2252     }
2253
2254     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2255     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2256     IDirect3DDevice9_SetVertexShader(device, NULL);
2257     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2258
2259     IDirect3DVertexDeclaration9_Release(decl);
2260     IDirect3DVertexShader9_Release(shader);
2261
2262     /* Z < 1.0 */
2263     color = getPixelColor(device, 28, 238);
2264     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2265
2266     /* 1.0 < z < 0.75 */
2267     color = getPixelColor(device, 31, 238);
2268     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2269     color = getPixelColor(device, 100, 238);
2270     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2271
2272     /* 0.75 < z < 0.0 */
2273     color = getPixelColor(device, 104, 238);
2274     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2275     color = getPixelColor(device, 318, 238);
2276     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2277
2278     /* 0.0 < z */
2279     color = getPixelColor(device, 321, 238);
2280     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2281
2282     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2283     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2284
2285     out:
2286     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2287     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2288     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2289     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2290     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2291     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2292 }
2293
2294 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2295 {
2296     D3DSURFACE_DESC desc;
2297     D3DLOCKED_RECT l;
2298     HRESULT hr;
2299     unsigned int x, y;
2300     DWORD *mem;
2301
2302     memset(&desc, 0, sizeof(desc));
2303     memset(&l, 0, sizeof(l));
2304     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2305     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2306     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2307     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2308     if(FAILED(hr)) return;
2309
2310     for(y = 0; y < desc.Height; y++)
2311     {
2312         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2313         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2314         {
2315             mem[x] = color;
2316         }
2317     }
2318     hr = IDirect3DSurface9_UnlockRect(surface);
2319     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2320 }
2321
2322 /* This tests a variety of possible StretchRect() situations */
2323 static void stretchrect_test(IDirect3DDevice9 *device)
2324 {
2325     HRESULT hr;
2326     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2327     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2328     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2329     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2330     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2331     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2332     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2333     IDirect3DSurface9 *orig_rt = NULL;
2334     IDirect3DSurface9 *backbuffer = NULL;
2335     DWORD color;
2336
2337     RECT src_rect64 = {0, 0, 64, 64};
2338     RECT src_rect64_flipy = {0, 64, 64, 0};
2339     RECT dst_rect64 = {0, 0, 64, 64};
2340     RECT dst_rect64_flipy = {0, 64, 64, 0};
2341
2342     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2343     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2344     if(!orig_rt) {
2345         goto out;
2346     }
2347
2348     /* Create our temporary surfaces in system memory */
2349     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2350     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2351     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2352     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2353
2354     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2355     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2356     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2357     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2358     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2359     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2360     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2361
2362     /* Create render target surfaces */
2363     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2364     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2365     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2366     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2367     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2368     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2369     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2370     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2371
2372     /* Create render target textures */
2373     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2374     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2375     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2376     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2377     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2378     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2379     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2380     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2381     if (tex_rt32) {
2382         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2383         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2384     }
2385     if (tex_rt64) {
2386         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2387         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2388     }
2389     if (tex_rt_dest64) {
2390         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2391         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2392     }
2393     if (tex_rt_dest64) {
2394         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2395         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2396     }
2397
2398     /* Create regular textures in D3DPOOL_DEFAULT */
2399     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2400     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2401     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2402     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2403     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2404     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2405     if (tex32) {
2406         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2407         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2408     }
2409     if (tex64) {
2410         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2411         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2412     }
2413     if (tex_dest64) {
2414         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2415         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2416     }
2417
2418     /*********************************************************************
2419      * Tests for when the source parameter is an offscreen plain surface *
2420      *********************************************************************/
2421
2422     /* Fill the offscreen 64x64 surface with green */
2423     if (surf_offscreen64)
2424         fill_surface(surf_offscreen64, 0xff00ff00);
2425
2426     /* offscreenplain ==> offscreenplain, same size */
2427     if(surf_offscreen64 && surf_offscreen_dest64) {
2428         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2429         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2430
2431         if (hr == D3D_OK) {
2432             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2433             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2434         }
2435
2436         /* Blit without scaling */
2437         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2438         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2439
2440         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2441         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2442         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2443
2444         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2445         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2446         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2447     }
2448
2449     /* offscreenplain ==> rendertarget texture, same size */
2450     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2451         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2452         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2453
2454         /* We can't lock rendertarget textures, so copy to our temp surface first */
2455         if (hr == D3D_OK) {
2456             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2457             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2458         }
2459
2460         if (hr == D3D_OK) {
2461             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2462             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2463         }
2464
2465         /* Blit without scaling */
2466         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2467         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2468
2469         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2470         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2471         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2472
2473         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2474         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2475         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2476     }
2477
2478     /* offscreenplain ==> rendertarget surface, same size */
2479     if(surf_offscreen64 && surf_rt_dest64) {
2480         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2481         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2482
2483         if (hr == D3D_OK) {
2484             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2485             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2486         }
2487
2488         /* Blit without scaling */
2489         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2490         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2491
2492         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2493         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2494         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2495
2496         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2497         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2498         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2499     }
2500
2501     /* offscreenplain ==> texture, same size (should fail) */
2502     if(surf_offscreen64 && surf_tex_dest64) {
2503         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2504         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2505     }
2506
2507     /* Fill the smaller offscreen surface with red */
2508     fill_surface(surf_offscreen32, 0xffff0000);
2509
2510     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2511     if(surf_offscreen32 && surf_offscreen64) {
2512         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2513         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2514     }
2515
2516     /* offscreenplain ==> rendertarget texture, scaling */
2517     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2518         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2519         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2520
2521         /* We can't lock rendertarget textures, so copy to our temp surface first */
2522         if (hr == D3D_OK) {
2523             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2524             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2525         }
2526
2527         if (hr == D3D_OK) {
2528             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2529             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2530         }
2531     }
2532
2533     /* offscreenplain ==> rendertarget surface, scaling */
2534     if(surf_offscreen32 && surf_rt_dest64) {
2535         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2536         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2537
2538         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2539         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2540     }
2541
2542     /* offscreenplain ==> texture, scaling (should fail) */
2543     if(surf_offscreen32 && surf_tex_dest64) {
2544         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2545         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2546     }
2547
2548     /************************************************************
2549      * Tests for when the source parameter is a regular texture *
2550      ************************************************************/
2551
2552     /* Fill the surface of the regular texture with blue */
2553     if (surf_tex64 && surf_temp64) {
2554         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2555         fill_surface(surf_temp64, 0xff0000ff);
2556         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2557         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2558     }
2559
2560     /* texture ==> offscreenplain, same size */
2561     if(surf_tex64 && surf_offscreen64) {
2562         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2563         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2564     }
2565
2566     /* texture ==> rendertarget texture, same size */
2567     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2568         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2569         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2570
2571         /* We can't lock rendertarget textures, so copy to our temp surface first */
2572         if (hr == D3D_OK) {
2573             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2574             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2575         }
2576
2577         if (hr == D3D_OK) {
2578             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2579             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2580         }
2581
2582         /* Blit without scaling */
2583         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2584         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2585
2586         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2587         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2588         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2589
2590         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2591         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2592         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2593     }
2594
2595     /* texture ==> rendertarget surface, same size */
2596     if(surf_tex64 && surf_rt_dest64) {
2597         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2598         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2599
2600         if (hr == D3D_OK) {
2601             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2602             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2603         }
2604
2605         /* Blit without scaling */
2606         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2607         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2608
2609         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2610         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2611         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2612
2613         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2614         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2615         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2616     }
2617
2618     /* texture ==> texture, same size (should fail) */
2619     if(surf_tex64 && surf_tex_dest64) {
2620         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2621         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2622     }
2623
2624     /* Fill the surface of the smaller regular texture with red */
2625     if (surf_tex32 && surf_temp32) {
2626         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2627         fill_surface(surf_temp32, 0xffff0000);
2628         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2629         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2630     }
2631
2632     /* texture ==> offscreenplain, scaling (should fail) */
2633     if(surf_tex32 && surf_offscreen64) {
2634         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2635         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2636     }
2637
2638     /* texture ==> rendertarget texture, scaling */
2639     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2640         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2641         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2642
2643         /* We can't lock rendertarget textures, so copy to our temp surface first */
2644         if (hr == D3D_OK) {
2645             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2646             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2647         }
2648
2649         if (hr == D3D_OK) {
2650             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2651             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2652         }
2653     }
2654
2655     /* texture ==> rendertarget surface, scaling */
2656     if(surf_tex32 && surf_rt_dest64) {
2657         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2658         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2659
2660         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2661         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2662     }
2663
2664     /* texture ==> texture, scaling (should fail) */
2665     if(surf_tex32 && surf_tex_dest64) {
2666         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2667         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2668     }
2669
2670     /*****************************************************************
2671      * Tests for when the source parameter is a rendertarget texture *
2672      *****************************************************************/
2673
2674     /* Fill the surface of the rendertarget texture with white */
2675     if (surf_tex_rt64 && surf_temp64) {
2676         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2677         fill_surface(surf_temp64, 0xffffffff);
2678         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2679         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2680     }
2681
2682     /* rendertarget texture ==> offscreenplain, same size */
2683     if(surf_tex_rt64 && surf_offscreen64) {
2684         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2685         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2686     }
2687
2688     /* rendertarget texture ==> rendertarget texture, same size */
2689     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2690         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2691         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2692
2693         /* We can't lock rendertarget textures, so copy to our temp surface first */
2694         if (hr == D3D_OK) {
2695             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2696             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2697         }
2698
2699         if (hr == D3D_OK) {
2700             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2701             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2702         }
2703
2704         /* Blit without scaling */
2705         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2706         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2707
2708         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2709         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2710         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2711
2712         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2713         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2714         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2715     }
2716
2717     /* rendertarget texture ==> rendertarget surface, same size */
2718     if(surf_tex_rt64 && surf_rt_dest64) {
2719         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2720         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2721
2722         if (hr == D3D_OK) {
2723             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2724             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2725         }
2726
2727         /* Blit without scaling */
2728         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2729         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2730
2731         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2732         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2733         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2734
2735         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2736         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2737         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2738     }
2739
2740     /* rendertarget texture ==> texture, same size (should fail) */
2741     if(surf_tex_rt64 && surf_tex_dest64) {
2742         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2743         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2744     }
2745
2746     /* Fill the surface of the smaller rendertarget texture with red */
2747     if (surf_tex_rt32 && surf_temp32) {
2748         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2749         fill_surface(surf_temp32, 0xffff0000);
2750         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2751         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2752     }
2753
2754     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2755     if(surf_tex_rt32 && surf_offscreen64) {
2756         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2757         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2758     }
2759
2760     /* rendertarget texture ==> rendertarget texture, scaling */
2761     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2762         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2763         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2764
2765         /* We can't lock rendertarget textures, so copy to our temp surface first */
2766         if (hr == D3D_OK) {
2767             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2768             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2769         }
2770
2771         if (hr == D3D_OK) {
2772             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2773             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2774         }
2775     }
2776
2777     /* rendertarget texture ==> rendertarget surface, scaling */
2778     if(surf_tex_rt32 && surf_rt_dest64) {
2779         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2780         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2781
2782         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2783         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2784     }
2785
2786     /* rendertarget texture ==> texture, scaling (should fail) */
2787     if(surf_tex_rt32 && surf_tex_dest64) {
2788         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2789         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2790     }
2791
2792     /*****************************************************************
2793      * Tests for when the source parameter is a rendertarget surface *
2794      *****************************************************************/
2795
2796     /* Fill the surface of the rendertarget surface with black */
2797     if (surf_rt64)
2798         fill_surface(surf_rt64, 0xff000000);
2799
2800     /* rendertarget texture ==> offscreenplain, same size */
2801     if(surf_rt64 && surf_offscreen64) {
2802         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2803         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2804     }
2805
2806     /* rendertarget surface ==> rendertarget texture, same size */
2807     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2808         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2809         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2810
2811         /* We can't lock rendertarget textures, so copy to our temp surface first */
2812         if (hr == D3D_OK) {
2813             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2814             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2815         }
2816
2817         if (hr == D3D_OK) {
2818             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2819             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2820         }
2821
2822         /* Blit without scaling */
2823         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2824         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2825
2826         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2827         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2828         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2829
2830         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2831         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2832         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2833     }
2834
2835     /* rendertarget surface ==> rendertarget surface, same size */
2836     if(surf_rt64 && surf_rt_dest64) {
2837         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2838         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2839
2840         if (hr == D3D_OK) {
2841             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2842             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2843         }
2844
2845         /* Blit without scaling */
2846         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2847         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2848
2849         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2850         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
2851         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2852
2853         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2854         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2855         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2856     }
2857
2858     /* rendertarget surface ==> texture, same size (should fail) */
2859     if(surf_rt64 && surf_tex_dest64) {
2860         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2861         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2862     }
2863
2864     /* Fill the surface of the smaller rendertarget texture with red */
2865     if (surf_rt32)
2866         fill_surface(surf_rt32, 0xffff0000);
2867
2868     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2869     if(surf_rt32 && surf_offscreen64) {
2870         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2871         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2872     }
2873
2874     /* rendertarget surface ==> rendertarget texture, scaling */
2875     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2876         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2877         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2878
2879         /* We can't lock rendertarget textures, so copy to our temp surface first */
2880         if (hr == D3D_OK) {
2881             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2882             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2883         }
2884
2885         if (hr == D3D_OK) {
2886             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2887             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2888         }
2889     }
2890
2891     /* rendertarget surface ==> rendertarget surface, scaling */
2892     if(surf_rt32 && surf_rt_dest64) {
2893         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2894         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2895
2896         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2897         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2898     }
2899
2900     /* rendertarget surface ==> texture, scaling (should fail) */
2901     if(surf_rt32 && surf_tex_dest64) {
2902         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2903         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2904     }
2905
2906     /* backbuffer ==> surface tests (no scaling) */
2907     if(backbuffer && surf_tex_rt_dest640_480)
2908     {
2909         RECT src_rect = {0, 0, 640, 480};
2910         RECT src_rect_flipy = {0, 480, 640, 0};
2911         RECT dst_rect = {0, 0, 640, 480};
2912         RECT dst_rect_flipy = {0, 480, 640, 0};
2913
2914         /* Blit with NULL rectangles */
2915         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
2916         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
2917
2918         /* Blit without scaling */
2919         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
2920         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2921
2922         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2923         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
2924         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2925
2926         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2927         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
2928         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2929     }
2930
2931     /* TODO: Test format conversions */
2932
2933
2934 out:
2935     /* Clean up */
2936     if (backbuffer)
2937         IDirect3DSurface9_Release(backbuffer);
2938     if (surf_rt32)
2939         IDirect3DSurface9_Release(surf_rt32);
2940     if (surf_rt64)
2941         IDirect3DSurface9_Release(surf_rt64);
2942     if (surf_rt_dest64)
2943         IDirect3DSurface9_Release(surf_rt_dest64);
2944     if (surf_temp32)
2945         IDirect3DSurface9_Release(surf_temp32);
2946     if (surf_temp64)
2947         IDirect3DSurface9_Release(surf_temp64);
2948     if (surf_offscreen32)
2949         IDirect3DSurface9_Release(surf_offscreen32);
2950     if (surf_offscreen64)
2951         IDirect3DSurface9_Release(surf_offscreen64);
2952     if (surf_offscreen_dest64)
2953         IDirect3DSurface9_Release(surf_offscreen_dest64);
2954
2955     if (tex_rt32) {
2956         if (surf_tex_rt32)
2957             IDirect3DSurface9_Release(surf_tex_rt32);
2958         IDirect3DTexture9_Release(tex_rt32);
2959     }
2960     if (tex_rt64) {
2961         if (surf_tex_rt64)
2962             IDirect3DSurface9_Release(surf_tex_rt64);
2963         IDirect3DTexture9_Release(tex_rt64);
2964     }
2965     if (tex_rt_dest64) {
2966         if (surf_tex_rt_dest64)
2967             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2968         IDirect3DTexture9_Release(tex_rt_dest64);
2969     }
2970     if (tex_rt_dest640_480) {
2971         if (surf_tex_rt_dest640_480)
2972             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
2973         IDirect3DTexture9_Release(tex_rt_dest640_480);
2974     }
2975     if (tex32) {
2976         if (surf_tex32)
2977             IDirect3DSurface9_Release(surf_tex32);
2978         IDirect3DTexture9_Release(tex32);
2979     }
2980     if (tex64) {
2981         if (surf_tex64)
2982             IDirect3DSurface9_Release(surf_tex64);
2983         IDirect3DTexture9_Release(tex64);
2984     }
2985     if (tex_dest64) {
2986         if (surf_tex_dest64)
2987             IDirect3DSurface9_Release(surf_tex_dest64);
2988         IDirect3DTexture9_Release(tex_dest64);
2989     }
2990
2991     if (orig_rt) {
2992         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2993         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2994         IDirect3DSurface9_Release(orig_rt);
2995     }
2996 }
2997
2998 static void maxmip_test(IDirect3DDevice9 *device)
2999 {
3000     IDirect3DTexture9 *texture = NULL;
3001     IDirect3DSurface9 *surface = NULL;
3002     HRESULT hr;
3003     DWORD color;
3004     static const struct
3005     {
3006         struct
3007         {
3008             float x, y, z;
3009             float s, t;
3010         }
3011         v[4];
3012     }
3013     quads[] =
3014     {
3015         {{
3016             {-1.0, -1.0,  0.0,  0.0,  0.0},
3017             {-1.0,  0.0,  0.0,  0.0,  1.0},
3018             { 0.0, -1.0,  0.0,  1.0,  0.0},
3019             { 0.0,  0.0,  0.0,  1.0,  1.0},
3020         }},
3021         {{
3022             { 0.0, -1.0,  0.0,  0.0,  0.0},
3023             { 0.0,  0.0,  0.0,  0.0,  1.0},
3024             { 1.0, -1.0,  0.0,  1.0,  0.0},
3025             { 1.0,  0.0,  0.0,  1.0,  1.0},
3026         }},
3027         {{
3028             { 0.0,  0.0,  0.0,  0.0,  0.0},
3029             { 0.0,  1.0,  0.0,  0.0,  1.0},
3030             { 1.0,  0.0,  0.0,  1.0,  0.0},
3031             { 1.0,  1.0,  0.0,  1.0,  1.0},
3032         }},
3033         {{
3034             {-1.0,  0.0,  0.0,  0.0,  0.0},
3035             {-1.0,  1.0,  0.0,  0.0,  1.0},
3036             { 0.0,  0.0,  0.0,  1.0,  0.0},
3037             { 0.0,  1.0,  0.0,  1.0,  1.0},
3038         }},
3039     };
3040
3041     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3042                                         &texture, NULL);
3043     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3044     if(!texture)
3045     {
3046         skip("Failed to create test texture\n");
3047         return;
3048     }
3049
3050     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3051     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3052     fill_surface(surface, 0xffff0000);
3053     IDirect3DSurface9_Release(surface);
3054     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3055     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3056     fill_surface(surface, 0xff00ff00);
3057     IDirect3DSurface9_Release(surface);
3058     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3059     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3060     fill_surface(surface, 0xff0000ff);
3061     IDirect3DSurface9_Release(surface);
3062
3063     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3064     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3065     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3066     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3067
3068     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3069     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3070
3071     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3072     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3073
3074     hr = IDirect3DDevice9_BeginScene(device);
3075     if(SUCCEEDED(hr))
3076     {
3077         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3078         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3079         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3080         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3081
3082         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3083         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3084         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3085         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3086
3087         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3088         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3089         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3090         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3091
3092         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3093         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3094         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3095         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3096         hr = IDirect3DDevice9_EndScene(device);
3097         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3098     }
3099
3100     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3101     color = getPixelColor(device, 160, 360);
3102     ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3103     color = getPixelColor(device, 480, 360);
3104     ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3105     color = getPixelColor(device, 480, 120);
3106     ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3107     color = getPixelColor(device, 160, 120);
3108     ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3109     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3110     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3111
3112     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3113     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3114
3115     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3116     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3117
3118     hr = IDirect3DDevice9_BeginScene(device);
3119     if(SUCCEEDED(hr))
3120     {
3121         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3122         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3123         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3124         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3125
3126         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3127         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3128         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3129         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3130
3131         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3132         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3133         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3134         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3135
3136         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3137         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3138         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3139         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3140         hr = IDirect3DDevice9_EndScene(device);
3141         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3142     }
3143
3144     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3145      * level 3 (> levels in texture) samples from the highest level in the
3146      * texture (level 2). */
3147     color = getPixelColor(device, 160, 360);
3148     ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3149     color = getPixelColor(device, 480, 360);
3150     ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3151     color = getPixelColor(device, 480, 120);
3152     ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3153     color = getPixelColor(device, 160, 120);
3154     ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3155     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3156     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3157
3158     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3159     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3160
3161     hr = IDirect3DDevice9_BeginScene(device);
3162     if(SUCCEEDED(hr))
3163     {
3164         DWORD ret;
3165
3166         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3167         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3168         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3169         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3170         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3171         ret = IDirect3DTexture9_SetLOD(texture, 1);
3172         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3173         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3174         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3175
3176         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3177         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3178         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3179         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3180         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3181         ret = IDirect3DTexture9_SetLOD(texture, 2);
3182         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3183         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3184         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3185
3186         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3187         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3188         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3189         ret = IDirect3DTexture9_SetLOD(texture, 1);
3190         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3191         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3192         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3193
3194         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3195         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3196         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3197         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3198         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3199         ret = IDirect3DTexture9_SetLOD(texture, 1);
3200         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3201         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3202         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3203         hr = IDirect3DDevice9_EndScene(device);
3204         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3205     }
3206
3207     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3208      * level 3 (> levels in texture) samples from the highest level in the
3209      * texture (level 2). */
3210     color = getPixelColor(device, 160, 360);
3211     ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3212     color = getPixelColor(device, 480, 360);
3213     ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3214     color = getPixelColor(device, 480, 120);
3215     ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3216     color = getPixelColor(device, 160, 120);
3217     ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3218
3219     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3220     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3221
3222     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3223     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3224     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3225     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3226     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3227     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3228     IDirect3DTexture9_Release(texture);
3229 }
3230
3231 static void release_buffer_test(IDirect3DDevice9 *device)
3232 {
3233     IDirect3DVertexBuffer9 *vb = NULL;
3234     IDirect3DIndexBuffer9 *ib = NULL;
3235     HRESULT hr;
3236     BYTE *data;
3237     LONG ref;
3238
3239     static const struct vertex quad[] = {
3240         {-1.0,      -1.0,       0.1,        0xffff0000},
3241         {-1.0,       1.0,       0.1,        0xffff0000},
3242         { 1.0,       1.0,       0.1,        0xffff0000},
3243
3244         {-1.0,      -1.0,       0.1,        0xff00ff00},
3245         {-1.0,       1.0,       0.1,        0xff00ff00},
3246         { 1.0,       1.0,       0.1,        0xff00ff00}
3247     };
3248     short indices[] = {3, 4, 5};
3249
3250     /* Index and vertex buffers should always be creatable */
3251     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3252                                               D3DPOOL_MANAGED, &vb, NULL);
3253     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3254     if(!vb) {
3255         skip("Failed to create a vertex buffer\n");
3256         return;
3257     }
3258     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3259     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3260     if(!ib) {
3261         skip("Failed to create an index buffer\n");
3262         return;
3263     }
3264
3265     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3266     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3267     memcpy(data, quad, sizeof(quad));
3268     hr = IDirect3DVertexBuffer9_Unlock(vb);
3269     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3270
3271     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3272     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3273     memcpy(data, indices, sizeof(indices));
3274     hr = IDirect3DIndexBuffer9_Unlock(ib);
3275     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3276
3277     hr = IDirect3DDevice9_SetIndices(device, ib);
3278     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3279     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3280     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3281     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3282     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3283
3284     /* Now destroy the bound index buffer and draw again */
3285     ref = IDirect3DIndexBuffer9_Release(ib);
3286     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3287
3288     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3289     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3290
3291     hr = IDirect3DDevice9_BeginScene(device);
3292     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3293     if(SUCCEEDED(hr))
3294     {
3295         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3296          * making assumptions about the indices or vertices
3297          */
3298         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3299         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3300         hr = IDirect3DDevice9_EndScene(device);
3301         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3302     }
3303
3304     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3305     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3306
3307     hr = IDirect3DDevice9_SetIndices(device, NULL);
3308     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3309     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3310     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3311
3312     /* Index buffer was already destroyed as part of the test */
3313     IDirect3DVertexBuffer9_Release(vb);
3314 }
3315
3316 static void float_texture_test(IDirect3DDevice9 *device)
3317 {
3318     IDirect3D9 *d3d = NULL;
3319     HRESULT hr;
3320     IDirect3DTexture9 *texture = NULL;
3321     D3DLOCKED_RECT lr;
3322     float *data;
3323     DWORD color;
3324     float quad[] = {
3325         -1.0,      -1.0,       0.1,     0.0,    0.0,
3326         -1.0,       1.0,       0.1,     0.0,    1.0,
3327          1.0,      -1.0,       0.1,     1.0,    0.0,
3328          1.0,       1.0,       0.1,     1.0,    1.0,
3329     };
3330
3331     memset(&lr, 0, sizeof(lr));
3332     IDirect3DDevice9_GetDirect3D(device, &d3d);
3333     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3334                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3335         skip("D3DFMT_R32F textures not supported\n");
3336         goto out;
3337     }
3338
3339     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3340                                         D3DPOOL_MANAGED, &texture, NULL);
3341     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3342     if(!texture) {
3343         skip("Failed to create R32F texture\n");
3344         goto out;
3345     }
3346
3347     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3348     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3349     data = lr.pBits;
3350     *data = 0.0;
3351     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3352     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3353
3354     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3355     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3356
3357     hr = IDirect3DDevice9_BeginScene(device);
3358     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3359     if(SUCCEEDED(hr))
3360     {
3361         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3362         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3363
3364         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3365         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3366
3367         hr = IDirect3DDevice9_EndScene(device);
3368         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3369     }
3370     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3371     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3372
3373     color = getPixelColor(device, 240, 320);
3374     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3375
3376     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3377     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3378
3379 out:
3380     if(texture) IDirect3DTexture9_Release(texture);
3381     IDirect3D9_Release(d3d);
3382 }
3383
3384 static void g16r16_texture_test(IDirect3DDevice9 *device)
3385 {
3386     IDirect3D9 *d3d = NULL;
3387     HRESULT hr;
3388     IDirect3DTexture9 *texture = NULL;
3389     D3DLOCKED_RECT lr;
3390     DWORD *data;
3391     DWORD color;
3392     float quad[] = {
3393        -1.0,      -1.0,       0.1,     0.0,    0.0,
3394        -1.0,       1.0,       0.1,     0.0,    1.0,
3395         1.0,      -1.0,       0.1,     1.0,    0.0,
3396         1.0,       1.0,       0.1,     1.0,    1.0,
3397     };
3398
3399     memset(&lr, 0, sizeof(lr));
3400     IDirect3DDevice9_GetDirect3D(device, &d3d);
3401     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3402        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3403            skip("D3DFMT_G16R16 textures not supported\n");
3404            goto out;
3405     }
3406
3407     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3408                                         D3DPOOL_MANAGED, &texture, NULL);
3409     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3410     if(!texture) {
3411         skip("Failed to create D3DFMT_G16R16 texture\n");
3412         goto out;
3413     }
3414
3415     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3416     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3417     data = lr.pBits;
3418     *data = 0x0f00f000;
3419     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3420     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3421
3422     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3423     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3424
3425     hr = IDirect3DDevice9_BeginScene(device);
3426     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3427     if(SUCCEEDED(hr))
3428     {
3429         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3430         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3431
3432         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3433         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3434
3435         hr = IDirect3DDevice9_EndScene(device);
3436         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3437     }
3438     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3439     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3440
3441     color = getPixelColor(device, 240, 320);
3442     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3443        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3444
3445     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3446     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3447
3448 out:
3449     if(texture) IDirect3DTexture9_Release(texture);
3450     IDirect3D9_Release(d3d);
3451 }
3452
3453 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3454 {
3455     HRESULT hr;
3456     IDirect3D9 *d3d;
3457     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3458     D3DCAPS9 caps;
3459     IDirect3DTexture9 *texture = NULL;
3460     IDirect3DVolumeTexture9 *volume = NULL;
3461     unsigned int x, y, z;
3462     D3DLOCKED_RECT lr;
3463     D3DLOCKED_BOX lb;
3464     DWORD color;
3465     UINT w, h;
3466     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3467     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3468                            0.0, 1.0, 0.0, 0.0,
3469                            0.0, 0.0, 1.0, 0.0,
3470                            0.0, 0.0, 0.0, 1.0};
3471     static const D3DVERTEXELEMENT9 decl_elements[] = {
3472         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3473         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3474         D3DDECL_END()
3475     };
3476     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3477         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3478         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3479         D3DDECL_END()
3480     };
3481     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3482         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3483         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3484         D3DDECL_END()
3485     };
3486     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3487                                                  0x00, 0xff, 0x00, 0x00,
3488                                                  0x00, 0x00, 0x00, 0x00,
3489                                                  0x00, 0x00, 0x00, 0x00};
3490
3491     memset(&lr, 0, sizeof(lr));
3492     memset(&lb, 0, sizeof(lb));
3493     IDirect3DDevice9_GetDirect3D(device, &d3d);
3494     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3495                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3496         fmt = D3DFMT_A16B16G16R16;
3497     }
3498     IDirect3D9_Release(d3d);
3499
3500     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3501     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3502     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3503     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3504     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3505     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3506     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3507     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3508     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3509     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3510     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3511     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3512     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3513     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3514     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3515     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3516     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3517     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3518     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3519     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3520     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3521     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3522     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3523     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3524
3525     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3526     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3527     w = min(1024, caps.MaxTextureWidth);
3528     h = min(1024, caps.MaxTextureHeight);
3529     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3530                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3531     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3532     if(!texture) {
3533         skip("Failed to create the test texture\n");
3534         return;
3535     }
3536
3537     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3538      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3539      * 1.0 in red and green for the x and y coords
3540      */
3541     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3542     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3543     for(y = 0; y < h; y++) {
3544         for(x = 0; x < w; x++) {
3545             double r_f = (double) y / (double) h;
3546             double g_f = (double) x / (double) w;
3547             if(fmt == D3DFMT_A16B16G16R16) {
3548                 unsigned short r, g;
3549                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3550                 r = (unsigned short) (r_f * 65536.0);
3551                 g = (unsigned short) (g_f * 65536.0);
3552                 dst[0] = r;
3553                 dst[1] = g;
3554                 dst[2] = 0;
3555                 dst[3] = 65535;
3556             } else {
3557                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3558                 unsigned char r = (unsigned char) (r_f * 255.0);
3559                 unsigned char g = (unsigned char) (g_f * 255.0);
3560                 dst[0] = 0;
3561                 dst[1] = g;
3562                 dst[2] = r;
3563                 dst[3] = 255;
3564             }
3565         }
3566     }
3567     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3568     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3569     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3570     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3571
3572     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3573     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3574     hr = IDirect3DDevice9_BeginScene(device);
3575     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3576     if(SUCCEEDED(hr))
3577     {
3578         float quad1[] = {
3579             -1.0,      -1.0,       0.1,     1.0,    1.0,
3580             -1.0,       0.0,       0.1,     1.0,    1.0,
3581              0.0,      -1.0,       0.1,     1.0,    1.0,
3582              0.0,       0.0,       0.1,     1.0,    1.0,
3583         };
3584         float quad2[] = {
3585             -1.0,       0.0,       0.1,     1.0,    1.0,
3586             -1.0,       1.0,       0.1,     1.0,    1.0,
3587              0.0,       0.0,       0.1,     1.0,    1.0,
3588              0.0,       1.0,       0.1,     1.0,    1.0,
3589         };
3590         float quad3[] = {
3591              0.0,       0.0,       0.1,     0.5,    0.5,
3592              0.0,       1.0,       0.1,     0.5,    0.5,
3593              1.0,       0.0,       0.1,     0.5,    0.5,
3594              1.0,       1.0,       0.1,     0.5,    0.5,
3595         };
3596         float quad4[] = {
3597              320,       480,       0.1,     1.0,    0.0,    1.0,
3598              320,       240,       0.1,     1.0,    0.0,    1.0,
3599              640,       480,       0.1,     1.0,    0.0,    1.0,
3600              640,       240,       0.1,     1.0,    0.0,    1.0,
3601         };
3602         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3603                           0.0, 0.0, 0.0, 0.0,
3604                           0.0, 0.0, 0.0, 0.0,
3605                           0.0, 0.0, 0.0, 0.0};
3606
3607         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3608         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3609         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3610         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3611         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3612
3613         /* What happens with transforms enabled? */
3614         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3615         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3616         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3617         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3618
3619         /* What happens if 4 coords are used, but only 2 given ?*/
3620         mat[8] = 1.0;
3621         mat[13] = 1.0;
3622         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3623         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3624         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3625         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3626         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3627         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3628
3629         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3630          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3631          * due to the coords in the vertices. (turns out red, indeed)
3632          */
3633         memset(mat, 0, sizeof(mat));
3634         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3635         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3636         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3637         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3638         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3639         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3640         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3641         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3642
3643         hr = IDirect3DDevice9_EndScene(device);
3644         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3645     }
3646     color = getPixelColor(device, 160, 360);
3647     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3648     color = getPixelColor(device, 160, 120);
3649     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3650     color = getPixelColor(device, 480, 120);
3651     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3652     color = getPixelColor(device, 480, 360);
3653     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3654     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3655     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3656
3657     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3658     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3659
3660     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3661     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3662     hr = IDirect3DDevice9_BeginScene(device);
3663     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3664     if(SUCCEEDED(hr))
3665     {
3666         float quad1[] = {
3667             -1.0,      -1.0,       0.1,     0.8,    0.2,
3668             -1.0,       0.0,       0.1,     0.8,    0.2,
3669              0.0,      -1.0,       0.1,     0.8,    0.2,
3670              0.0,       0.0,       0.1,     0.8,    0.2,
3671         };
3672         float quad2[] = {
3673             -1.0,       0.0,       0.1,     0.5,    1.0,
3674             -1.0,       1.0,       0.1,     0.5,    1.0,
3675              0.0,       0.0,       0.1,     0.5,    1.0,
3676              0.0,       1.0,       0.1,     0.5,    1.0,
3677         };
3678         float quad3[] = {
3679              0.0,       0.0,       0.1,     0.5,    1.0,
3680              0.0,       1.0,       0.1,     0.5,    1.0,
3681              1.0,       0.0,       0.1,     0.5,    1.0,
3682              1.0,       1.0,       0.1,     0.5,    1.0,
3683         };
3684         float quad4[] = {
3685              0.0,      -1.0,       0.1,     0.8,    0.2,
3686              0.0,       0.0,       0.1,     0.8,    0.2,
3687              1.0,      -1.0,       0.1,     0.8,    0.2,
3688              1.0,       0.0,       0.1,     0.8,    0.2,
3689         };
3690         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3691                           0.0, 0.0, 0.0, 0.0,
3692                           0.0, 1.0, 0.0, 0.0,
3693                           0.0, 0.0, 0.0, 0.0};
3694
3695         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3696          */
3697         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3698         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3699         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3700         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3701
3702         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3703         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3704
3705         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3706          * it behaves like COUNT2 because normal textures require 2 coords
3707          */
3708         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3709         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3710         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3711         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3712
3713         /* Just to be sure, the same as quad2 above */
3714         memset(mat, 0, sizeof(mat));
3715         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3716         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3717         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3718         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3719         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3720         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3721
3722         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3723          * used? And what happens to the first?
3724          */
3725         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3726         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3727         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3728         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3729
3730         hr = IDirect3DDevice9_EndScene(device);
3731         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3732     }
3733     color = getPixelColor(device, 160, 360);
3734     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3735     color = getPixelColor(device, 160, 120);
3736     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3737     color = getPixelColor(device, 480, 120);
3738     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3739        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3740     color = getPixelColor(device, 480, 360);
3741     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3742        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3743     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3744     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3745
3746     IDirect3DTexture9_Release(texture);
3747
3748     /* Test projected textures, without any fancy matrices */
3749     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3750     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3751     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3752     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3753     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3754     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3755     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3756     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3757
3758     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3759     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3760     for(x = 0; x < 4; x++) {
3761         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3762     }
3763     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3764     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3765     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3766     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3767
3768     hr = IDirect3DDevice9_BeginScene(device);
3769     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3770     if(SUCCEEDED(hr))
3771     {
3772         const float proj_quads[] = {
3773            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3774             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3775            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3776             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3777            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3778             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3779            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3780             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3781         };
3782
3783         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3784         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3785         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3786         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3787
3788         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3789         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3790         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3791         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3792
3793         hr = IDirect3DDevice9_EndScene(device);
3794         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3795     }
3796
3797     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3798     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3799     IDirect3DTexture9_Release(texture);
3800
3801     color = getPixelColor(device, 158, 118);
3802     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3803     color = getPixelColor(device, 162, 118);
3804     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3805     color = getPixelColor(device, 158, 122);
3806     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3807     color = getPixelColor(device, 162, 122);
3808     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3809
3810     color = getPixelColor(device, 158, 178);
3811     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3812     color = getPixelColor(device, 162, 178);
3813     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3814     color = getPixelColor(device, 158, 182);
3815     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3816     color = getPixelColor(device, 162, 182);
3817     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3818
3819     color = getPixelColor(device, 318, 118);
3820     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3821     color = getPixelColor(device, 322, 118);
3822     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3823     color = getPixelColor(device, 318, 122);
3824     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3825     color = getPixelColor(device, 322, 122);
3826     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3827
3828     color = getPixelColor(device, 318, 178);
3829     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3830     color = getPixelColor(device, 322, 178);
3831     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3832     color = getPixelColor(device, 318, 182);
3833     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3834     color = getPixelColor(device, 322, 182);
3835     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3836
3837     color = getPixelColor(device, 238, 298);
3838     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3839     color = getPixelColor(device, 242, 298);
3840     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3841     color = getPixelColor(device, 238, 302);
3842     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3843     color = getPixelColor(device, 242, 302);
3844     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3845
3846     color = getPixelColor(device, 238, 388);
3847     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3848     color = getPixelColor(device, 242, 388);
3849     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3850     color = getPixelColor(device, 238, 392);
3851     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3852     color = getPixelColor(device, 242, 392);
3853     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3854
3855     color = getPixelColor(device, 478, 298);
3856     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3857     color = getPixelColor(device, 482, 298);
3858     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3859     color = getPixelColor(device, 478, 302);
3860     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3861     color = getPixelColor(device, 482, 302);
3862     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3863
3864     color = getPixelColor(device, 478, 388);
3865     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3866     color = getPixelColor(device, 482, 388);
3867     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3868     color = getPixelColor(device, 478, 392);
3869     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3870     color = getPixelColor(device, 482, 392);
3871     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3872
3873     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3874     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3875
3876     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3877     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3878     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3879      * Thus watch out if sampling from texels between 0 and 1.
3880      */
3881     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3882     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3883        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3884     if(!volume) {
3885         skip("Failed to create a volume texture\n");
3886         goto out;
3887     }
3888
3889     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3890     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3891     for(z = 0; z < 32; z++) {
3892         for(y = 0; y < 32; y++) {
3893             for(x = 0; x < 32; x++) {
3894                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3895                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3896                 float r_f = (float) x / 31.0;
3897                 float g_f = (float) y / 31.0;
3898                 float b_f = (float) z / 31.0;
3899
3900                 if(fmt == D3DFMT_A16B16G16R16) {
3901                     unsigned short *mem_s = mem;
3902                     mem_s[0]  = r_f * 65535.0;
3903                     mem_s[1]  = g_f * 65535.0;
3904                     mem_s[2]  = b_f * 65535.0;
3905                     mem_s[3]  = 65535;
3906                 } else {
3907                     unsigned char *mem_c = mem;
3908                     mem_c[0]  = b_f * 255.0;
3909                     mem_c[1]  = g_f * 255.0;
3910                     mem_c[2]  = r_f * 255.0;
3911                     mem_c[3]  = 255;
3912                 }
3913             }
3914         }
3915     }
3916     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3917     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3918
3919     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3920     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3921
3922     hr = IDirect3DDevice9_BeginScene(device);
3923     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3924     if(SUCCEEDED(hr))
3925     {
3926         float quad1[] = {
3927             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3928             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3929              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3930              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3931         };
3932         float quad2[] = {
3933             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3934             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3935              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3936              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3937         };
3938         float quad3[] = {
3939              0.0,       0.0,       0.1,     0.0,    0.0,
3940              0.0,       1.0,       0.1,     0.0,    0.0,
3941              1.0,       0.0,       0.1,     0.0,    0.0,
3942              1.0,       1.0,       0.1,     0.0,    0.0
3943         };
3944         float quad4[] = {
3945              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3946              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3947              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3948              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3949         };
3950         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3951                          0.0, 0.0, 1.0, 0.0,
3952                          0.0, 1.0, 0.0, 0.0,
3953                          0.0, 0.0, 0.0, 1.0};
3954         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3955         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3956
3957         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3958          * values
3959          */
3960         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3961         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3962         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3963         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3964         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3965         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3966
3967         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3968          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3969          * otherwise the w will be missing(blue).
3970          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3971          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3972          */
3973         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3974         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3975         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3976         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3977
3978         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
3979         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3980         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3981         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3982         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3983         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3984         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3985         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3986         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3987
3988         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3989          * disable. ATI extends it up to the amount of values needed for the volume texture
3990          */
3991         memset(mat, 0, sizeof(mat));
3992         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3993         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3994         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3995         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3996         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3997         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3998         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3999         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4000
4001         hr = IDirect3DDevice9_EndScene(device);
4002         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4003     }
4004
4005     color = getPixelColor(device, 160, 360);
4006     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4007     color = getPixelColor(device, 160, 120);
4008     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4009        "quad 2 has color %08x, expected 0x00ffff00\n", color);
4010     color = getPixelColor(device, 480, 120);
4011     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4012     color = getPixelColor(device, 480, 360);
4013     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4014
4015     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4016     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4017
4018     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4019     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4020     hr = IDirect3DDevice9_BeginScene(device);
4021     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4022     if(SUCCEEDED(hr))
4023     {
4024         float quad1[] = {
4025             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4026             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4027              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4028              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4029         };
4030         float quad2[] = {
4031             -1.0,       0.0,       0.1,
4032             -1.0,       1.0,       0.1,
4033              0.0,       0.0,       0.1,
4034              0.0,       1.0,       0.1,
4035         };
4036         float quad3[] = {
4037              0.0,       0.0,       0.1,     1.0,
4038              0.0,       1.0,       0.1,     1.0,
4039              1.0,       0.0,       0.1,     1.0,
4040              1.0,       1.0,       0.1,     1.0
4041         };
4042         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4043                            0.0, 0.0, 0.0, 0.0,
4044                            0.0, 0.0, 0.0, 0.0,
4045                            0.0, 1.0, 0.0, 0.0};
4046         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4047                            1.0, 0.0, 0.0, 0.0,
4048                            0.0, 1.0, 0.0, 0.0,
4049                            0.0, 0.0, 1.0, 0.0};
4050         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4051         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4052
4053         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4054          * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4055          * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4056          * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4057          * 4th *input* coordinate.
4058          */
4059         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4060         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4061         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4062         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4063         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4064         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4065
4066         /* None passed */
4067         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4068         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4069         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4070         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4071         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4072         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4073
4074         /* 4 used, 1 passed */
4075         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4076         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4077         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4078         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4079         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4080         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4081
4082         hr = IDirect3DDevice9_EndScene(device);
4083         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4084     }
4085     color = getPixelColor(device, 160, 360);
4086     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4087     color = getPixelColor(device, 160, 120);
4088     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4089     color = getPixelColor(device, 480, 120);
4090     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4091     /* Quad4: unused */
4092
4093     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4094     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4095
4096     IDirect3DVolumeTexture9_Release(volume);
4097
4098     out:
4099     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4100     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4101     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4102     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4103     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4104     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4105     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4106     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4107     IDirect3DVertexDeclaration9_Release(decl);
4108     IDirect3DVertexDeclaration9_Release(decl2);
4109     IDirect3DVertexDeclaration9_Release(decl3);
4110 }
4111
4112 static void texdepth_test(IDirect3DDevice9 *device)
4113 {
4114     IDirect3DPixelShader9 *shader;
4115     HRESULT hr;
4116     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4117     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4118     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4119     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4120     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4121     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4122     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4123     DWORD shader_code[] = {
4124         0xffff0104,                                                                 /* ps_1_4               */
4125         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4126         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4127         0x0000fffd,                                                                 /* phase                */
4128         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4129         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4130         0x0000ffff                                                                  /* end                  */
4131     };
4132     DWORD color;
4133     float vertex[] = {
4134        -1.0,   -1.0,    0.0,
4135         1.0,   -1.0,    1.0,
4136        -1.0,    1.0,    0.0,
4137         1.0,    1.0,    1.0
4138     };
4139
4140     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4141     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4142
4143     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4144     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4145     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4146     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4147     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4148     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4149     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4150     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4151     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4152     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4153
4154     /* Fill the depth buffer with a gradient */
4155     hr = IDirect3DDevice9_BeginScene(device);
4156     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4157     if(SUCCEEDED(hr))
4158     {
4159         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4160         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4161         hr = IDirect3DDevice9_EndScene(device);
4162         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4163     }
4164
4165     /* Now perform the actual tests. Same geometry, but with the shader */
4166     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4167     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4168     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4169     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4170     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4171     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4172
4173     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4174     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4175     hr = IDirect3DDevice9_BeginScene(device);
4176     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4177     if(SUCCEEDED(hr))
4178     {
4179         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4180         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4181
4182         hr = IDirect3DDevice9_EndScene(device);
4183         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4184     }
4185
4186     color = getPixelColor(device, 158, 240);
4187     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4188     color = getPixelColor(device, 162, 240);
4189     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4190
4191     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4192     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4193
4194     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4195     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4196
4197     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4198     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4199     hr = IDirect3DDevice9_BeginScene(device);
4200     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4201     if(SUCCEEDED(hr))
4202     {
4203         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4204         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4205
4206         hr = IDirect3DDevice9_EndScene(device);
4207         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4208     }
4209
4210     color = getPixelColor(device, 318, 240);
4211     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4212     color = getPixelColor(device, 322, 240);
4213     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4214
4215     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4216     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4217
4218     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4219     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4220
4221     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4222     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4223     hr = IDirect3DDevice9_BeginScene(device);
4224     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4225     if(SUCCEEDED(hr))
4226     {
4227         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4228         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4229
4230         hr = IDirect3DDevice9_EndScene(device);
4231         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4232     }
4233
4234     color = getPixelColor(device, 1, 240);
4235     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4236
4237     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4238     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4239
4240     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4241     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4242
4243     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4244     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4245     hr = IDirect3DDevice9_BeginScene(device);
4246     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4247     if(SUCCEEDED(hr))
4248     {
4249         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4250         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4251
4252         hr = IDirect3DDevice9_EndScene(device);
4253         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4254     }
4255     color = getPixelColor(device, 318, 240);
4256     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4257     color = getPixelColor(device, 322, 240);
4258     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4259
4260     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4261     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4262
4263     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4264     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4265
4266     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4267     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4268     hr = IDirect3DDevice9_BeginScene(device);
4269     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4270     if(SUCCEEDED(hr))
4271     {
4272         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4273         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4274
4275         hr = IDirect3DDevice9_EndScene(device);
4276         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4277     }
4278
4279     color = getPixelColor(device, 1, 240);
4280     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4281
4282     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4283     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4284
4285     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4286     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4287
4288     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4289     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4290     hr = IDirect3DDevice9_BeginScene(device);
4291     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4292     if(SUCCEEDED(hr))
4293     {
4294         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4295         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4296
4297         hr = IDirect3DDevice9_EndScene(device);
4298         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4299     }
4300
4301     color = getPixelColor(device, 638, 240);
4302     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4303
4304     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4305     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4306
4307     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4308     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4309
4310     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4311     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4312     hr = IDirect3DDevice9_BeginScene(device);
4313     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4314     if(SUCCEEDED(hr))
4315     {
4316         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4317         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4318
4319         hr = IDirect3DDevice9_EndScene(device);
4320         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4321     }
4322
4323     color = getPixelColor(device, 638, 240);
4324     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4325
4326     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4327     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4328
4329     /* Cleanup */
4330     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4331     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4332     IDirect3DPixelShader9_Release(shader);
4333
4334     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4335     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4336     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4337     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4338 }
4339
4340 static void texkill_test(IDirect3DDevice9 *device)
4341 {
4342     IDirect3DPixelShader9 *shader;
4343     HRESULT hr;
4344     DWORD color;
4345
4346     const float vertex[] = {
4347     /*                          bottom  top    right    left */
4348         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4349          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4350         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4351          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4352     };
4353
4354     DWORD shader_code_11[] = {
4355     0xffff0101,                                                             /* ps_1_1                     */
4356     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4357     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4358     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4359     0x0000ffff                                                              /* end                        */
4360     };
4361     DWORD shader_code_20[] = {
4362     0xffff0200,                                                             /* ps_2_0                     */
4363     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4364     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4365     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4366     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4367     0x0000ffff                                                              /* end                        */
4368     };
4369
4370     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4371     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4372     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4373     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4374
4375     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4376     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4377     hr = IDirect3DDevice9_BeginScene(device);
4378     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4379     if(SUCCEEDED(hr))
4380     {
4381         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4382         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4383         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4384         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4385         hr = IDirect3DDevice9_EndScene(device);
4386         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4387     }
4388     color = getPixelColor(device, 63, 46);
4389     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4390     color = getPixelColor(device, 66, 46);
4391     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4392     color = getPixelColor(device, 63, 49);
4393     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4394     color = getPixelColor(device, 66, 49);
4395     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4396
4397     color = getPixelColor(device, 578, 46);
4398     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4399     color = getPixelColor(device, 575, 46);
4400     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4401     color = getPixelColor(device, 578, 49);
4402     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4403     color = getPixelColor(device, 575, 49);
4404     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4405
4406     color = getPixelColor(device, 63, 430);
4407     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4408     color = getPixelColor(device, 63, 433);
4409     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4410     color = getPixelColor(device, 66, 433);
4411     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4412     color = getPixelColor(device, 66, 430);
4413     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4414
4415     color = getPixelColor(device, 578, 430);
4416     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4417     color = getPixelColor(device, 578, 433);
4418     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4419     color = getPixelColor(device, 575, 433);
4420     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4421     color = getPixelColor(device, 575, 430);
4422     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4423
4424     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4425     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4426
4427     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4428     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4429     IDirect3DPixelShader9_Release(shader);
4430
4431     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4432     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4433     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4434     if(FAILED(hr)) {
4435         skip("Failed to create 2.0 test shader, most likely not supported\n");
4436         return;
4437     }
4438
4439     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4440     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4441     hr = IDirect3DDevice9_BeginScene(device);
4442     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4443     if(SUCCEEDED(hr))
4444     {
4445         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4446         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4447         hr = IDirect3DDevice9_EndScene(device);
4448         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4449     }
4450
4451     color = getPixelColor(device, 63, 46);
4452     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4453     color = getPixelColor(device, 66, 46);
4454     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4455     color = getPixelColor(device, 63, 49);
4456     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4457     color = getPixelColor(device, 66, 49);
4458     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4459
4460     color = getPixelColor(device, 578, 46);
4461     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4462     color = getPixelColor(device, 575, 46);
4463     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4464     color = getPixelColor(device, 578, 49);
4465     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4466     color = getPixelColor(device, 575, 49);
4467     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4468
4469     color = getPixelColor(device, 63, 430);
4470     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4471     color = getPixelColor(device, 63, 433);
4472     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4473     color = getPixelColor(device, 66, 433);
4474     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4475     color = getPixelColor(device, 66, 430);
4476     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4477
4478     color = getPixelColor(device, 578, 430);
4479     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4480     color = getPixelColor(device, 578, 433);
4481     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4482     color = getPixelColor(device, 575, 433);
4483     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4484     color = getPixelColor(device, 575, 430);
4485     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4486
4487     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4488     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4489
4490     /* Cleanup */
4491     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4492     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4493     IDirect3DPixelShader9_Release(shader);
4494 }
4495
4496 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4497 {
4498     IDirect3D9 *d3d9;
4499     HRESULT hr;
4500     IDirect3DTexture9 *texture;
4501     IDirect3DPixelShader9 *shader;
4502     IDirect3DPixelShader9 *shader2;
4503     D3DLOCKED_RECT lr;
4504     DWORD color;
4505     DWORD shader_code[] = {
4506         0xffff0101,                             /* ps_1_1       */
4507         0x00000042, 0xb00f0000,                 /* tex t0       */
4508         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4509         0x0000ffff                              /* end          */
4510     };
4511     DWORD shader_code2[] = {
4512         0xffff0101,                             /* ps_1_1       */
4513         0x00000042, 0xb00f0000,                 /* tex t0       */
4514         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4515         0x0000ffff                              /* end          */
4516     };
4517
4518     float quad[] = {
4519        -1.0,   -1.0,   0.1,     0.5,    0.5,
4520         1.0,   -1.0,   0.1,     0.5,    0.5,
4521        -1.0,    1.0,   0.1,     0.5,    0.5,
4522         1.0,    1.0,   0.1,     0.5,    0.5,
4523     };
4524
4525     memset(&lr, 0, sizeof(lr));
4526     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4527     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4528                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4529     IDirect3D9_Release(d3d9);
4530     if(FAILED(hr)) {
4531         skip("No D3DFMT_X8L8V8U8 support\n");
4532         return;
4533     };
4534
4535     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4536     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4537
4538     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4539     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4540     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4541     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4542     *((DWORD *) lr.pBits) = 0x11ca3141;
4543     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4544     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4545
4546     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4547     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4548     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4549     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4550
4551     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4552     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4553     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4554     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4555     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4556     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4557
4558     hr = IDirect3DDevice9_BeginScene(device);
4559     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4560     if(SUCCEEDED(hr))
4561     {
4562         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4563         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4564
4565         hr = IDirect3DDevice9_EndScene(device);
4566         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4567     }
4568     color = getPixelColor(device, 578, 430);
4569     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4570        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4571     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4572     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4573
4574     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4575     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4576     hr = IDirect3DDevice9_BeginScene(device);
4577     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4578     if(SUCCEEDED(hr))
4579     {
4580         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4581         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4582
4583         hr = IDirect3DDevice9_EndScene(device);
4584         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4585     }
4586     color = getPixelColor(device, 578, 430);
4587     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4588     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4589     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4590
4591     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4592     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4593     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4594     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4595     IDirect3DPixelShader9_Release(shader);
4596     IDirect3DPixelShader9_Release(shader2);
4597     IDirect3DTexture9_Release(texture);
4598 }
4599
4600 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4601 {
4602     HRESULT hr;
4603     IDirect3D9 *d3d;
4604     IDirect3DTexture9 *texture = NULL;
4605     IDirect3DSurface9 *surface;
4606     DWORD color;
4607     const RECT r1 = {256, 256, 512, 512};
4608     const RECT r2 = {512, 256, 768, 512};
4609     const RECT r3 = {256, 512, 512, 768};
4610     const RECT r4 = {512, 512, 768, 768};
4611     unsigned int x, y;
4612     D3DLOCKED_RECT lr;
4613     memset(&lr, 0, sizeof(lr));
4614
4615     IDirect3DDevice9_GetDirect3D(device, &d3d);
4616     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4617        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4618         skip("No autogenmipmap support\n");
4619         IDirect3D9_Release(d3d);
4620         return;
4621     }
4622     IDirect3D9_Release(d3d);
4623
4624     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4625     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4626
4627     /* Make the mipmap big, so that a smaller mipmap is used
4628      */
4629     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4630                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4631     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4632
4633     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4634     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4635     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4636     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4637     for(y = 0; y < 1024; y++) {
4638         for(x = 0; x < 1024; x++) {
4639             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4640             POINT pt;
4641
4642             pt.x = x;
4643             pt.y = y;
4644             if(PtInRect(&r1, pt)) {
4645                 *dst = 0xffff0000;
4646             } else if(PtInRect(&r2, pt)) {
4647                 *dst = 0xff00ff00;
4648             } else if(PtInRect(&r3, pt)) {
4649                 *dst = 0xff0000ff;
4650             } else if(PtInRect(&r4, pt)) {
4651                 *dst = 0xff000000;
4652             } else {
4653                 *dst = 0xffffffff;
4654             }
4655         }
4656     }
4657     hr = IDirect3DSurface9_UnlockRect(surface);
4658     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4659     IDirect3DSurface9_Release(surface);
4660
4661     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4662     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4663     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4664     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4665
4666     hr = IDirect3DDevice9_BeginScene(device);
4667     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4668     if(SUCCEEDED(hr)) {
4669         const float quad[] =  {
4670            -0.5,   -0.5,    0.1,    0.0,    0.0,
4671            -0.5,    0.5,    0.1,    0.0,    1.0,
4672             0.5,   -0.5,    0.1,    1.0,    0.0,
4673             0.5,    0.5,    0.1,    1.0,    1.0
4674         };
4675
4676         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4677         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4678         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4679         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4680         hr = IDirect3DDevice9_EndScene(device);
4681         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4682     }
4683     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4684     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4685     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4686     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4687     IDirect3DTexture9_Release(texture);
4688
4689     color = getPixelColor(device, 200, 200);
4690     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4691     color = getPixelColor(device, 280, 200);
4692     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4693     color = getPixelColor(device, 360, 200);
4694     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4695     color = getPixelColor(device, 440, 200);
4696     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4697     color = getPixelColor(device, 200, 270);
4698     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4699     color = getPixelColor(device, 280, 270);
4700     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4701     color = getPixelColor(device, 360, 270);
4702     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4703     color = getPixelColor(device, 440, 270);
4704     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4705     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4706     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4707 }
4708
4709 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4710 {
4711     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4712     IDirect3DVertexDeclaration9 *decl;
4713     HRESULT hr;
4714     DWORD color;
4715     DWORD shader_code_11[] =  {
4716         0xfffe0101,                                         /* vs_1_1           */
4717         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4718         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4719         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4720         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4721         0x0000ffff                                          /* end              */
4722     };
4723     DWORD shader_code_11_2[] =  {
4724         0xfffe0101,                                         /* vs_1_1           */
4725         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4726         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4727         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4728         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4729         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4730         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4731         0x0000ffff                                          /* end              */
4732     };
4733     DWORD shader_code_20[] =  {
4734         0xfffe0200,                                         /* vs_2_0           */
4735         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4736         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4737         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4738         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4739         0x0000ffff                                          /* end              */
4740     };
4741     DWORD shader_code_20_2[] =  {
4742         0xfffe0200,                                         /* vs_2_0           */
4743         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4744         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4745         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4746         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4747         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4748         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4749         0x0000ffff                                          /* end              */
4750     };
4751     static const D3DVERTEXELEMENT9 decl_elements[] = {
4752         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4753         D3DDECL_END()
4754     };
4755     float quad1[] = {
4756         -1.0,   -1.0,   0.1,
4757          0.0,   -1.0,   0.1,
4758         -1.0,    0.0,   0.1,
4759          0.0,    0.0,   0.1
4760     };
4761     float quad2[] = {
4762          0.0,   -1.0,   0.1,
4763          1.0,   -1.0,   0.1,
4764          0.0,    0.0,   0.1,
4765          1.0,    0.0,   0.1
4766     };
4767     float quad3[] = {
4768          0.0,    0.0,   0.1,
4769          1.0,    0.0,   0.1,
4770          0.0,    1.0,   0.1,
4771          1.0,    1.0,   0.1
4772     };
4773     float quad4[] = {
4774         -1.0,    0.0,   0.1,
4775          0.0,    0.0,   0.1,
4776         -1.0,    1.0,   0.1,
4777          0.0,    1.0,   0.1
4778     };
4779     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4780     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4781
4782     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4783     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4784
4785     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4786     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4787     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4788     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4789     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4790     if(FAILED(hr)) shader_20 = NULL;
4791     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4792     if(FAILED(hr)) shader_20_2 = NULL;
4793     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4794     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4795
4796     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4797     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4798     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4799     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4800     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4801     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4802
4803     hr = IDirect3DDevice9_BeginScene(device);
4804     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4805     if(SUCCEEDED(hr))
4806     {
4807         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4808         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4809         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4810         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4811
4812         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4813         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4814         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4815         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4816
4817         if(shader_20) {
4818             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4819             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4820             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4821             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4822         }
4823
4824         if(shader_20_2) {
4825             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4826             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4827             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4828             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4829         }
4830
4831         hr = IDirect3DDevice9_EndScene(device);
4832         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4833     }
4834
4835     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4836     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4837     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4838     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4839
4840     color = getPixelColor(device, 160, 360);
4841     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4842        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4843     color = getPixelColor(device, 480, 360);
4844     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4845        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4846     if(shader_20) {
4847         color = getPixelColor(device, 480, 120);
4848         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4849            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4850     }
4851     if(shader_20_2) {
4852         color = getPixelColor(device, 160, 120);
4853         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4854            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4855     }
4856     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4857     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4858
4859     IDirect3DVertexDeclaration9_Release(decl);
4860     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4861     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4862     IDirect3DVertexShader9_Release(shader_11_2);
4863     IDirect3DVertexShader9_Release(shader_11);
4864 }
4865
4866 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4867 {
4868     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4869     HRESULT hr;
4870     DWORD color;
4871     DWORD shader_code_11[] =  {
4872         0xffff0101,                                         /* ps_1_1           */
4873         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4874         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4875         0x0000ffff                                          /* end              */
4876     };
4877     DWORD shader_code_12[] =  {
4878         0xffff0102,                                         /* ps_1_2           */
4879         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4880         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4881         0x0000ffff                                          /* end              */
4882     };
4883     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4884      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4885      * During development of this test, 1.3 shaders were verified too
4886      */
4887     DWORD shader_code_14[] =  {
4888         0xffff0104,                                         /* ps_1_4           */
4889         /* Try to make one constant local. It gets clamped too, although the binary contains
4890          * the bigger numbers
4891          */
4892         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4893         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4894         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4895         0x0000ffff                                          /* end              */
4896     };
4897     DWORD shader_code_20[] =  {
4898         0xffff0200,                                         /* ps_2_0           */
4899         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4900         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4901         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4902         0x0000ffff                                          /* end              */
4903     };
4904     float quad1[] = {
4905         -1.0,   -1.0,   0.1,
4906          0.0,   -1.0,   0.1,
4907         -1.0,    0.0,   0.1,
4908          0.0,    0.0,   0.1
4909     };
4910     float quad2[] = {
4911          0.0,   -1.0,   0.1,
4912          1.0,   -1.0,   0.1,
4913          0.0,    0.0,   0.1,
4914          1.0,    0.0,   0.1
4915     };
4916     float quad3[] = {
4917          0.0,    0.0,   0.1,
4918          1.0,    0.0,   0.1,
4919          0.0,    1.0,   0.1,
4920          1.0,    1.0,   0.1
4921     };
4922     float quad4[] = {
4923         -1.0,    0.0,   0.1,
4924          0.0,    0.0,   0.1,
4925         -1.0,    1.0,   0.1,
4926          0.0,    1.0,   0.1
4927     };
4928     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4929     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4930
4931     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4932     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4933
4934     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4935     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4936     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4937     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4938     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4939     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4940     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4941     if(FAILED(hr)) shader_20 = NULL;
4942
4943     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4944     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4945     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4946     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4947     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4948     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4949
4950     hr = IDirect3DDevice9_BeginScene(device);
4951     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4952     if(SUCCEEDED(hr))
4953     {
4954         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4955         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4956         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4957         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4958
4959         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4960         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4961         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4962         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4963
4964         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4965         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4966         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4967         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4968
4969         if(shader_20) {
4970             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4971             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4972             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4973             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4974         }
4975
4976         hr = IDirect3DDevice9_EndScene(device);
4977         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4978     }
4979     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4980     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4981
4982     color = getPixelColor(device, 160, 360);
4983     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4984        "quad 1 has color %08x, expected 0x00808000\n", color);
4985     color = getPixelColor(device, 480, 360);
4986     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4987        "quad 2 has color %08x, expected 0x00808000\n", color);
4988     color = getPixelColor(device, 480, 120);
4989     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4990        "quad 3 has color %08x, expected 0x00808000\n", color);
4991     if(shader_20) {
4992         color = getPixelColor(device, 160, 120);
4993         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4994            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4995     }
4996     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4997     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4998
4999     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5000     IDirect3DPixelShader9_Release(shader_14);
5001     IDirect3DPixelShader9_Release(shader_12);
5002     IDirect3DPixelShader9_Release(shader_11);
5003 }
5004
5005 static void dp2add_ps_test(IDirect3DDevice9 *device)
5006 {
5007     IDirect3DPixelShader9 *shader_dp2add = NULL;
5008     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5009     HRESULT hr;
5010     DWORD color;
5011
5012     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
5013      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5014      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
5015      * r0 first.
5016      * The result here for the r,g,b components should be roughly 0.5:
5017      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5018     static const DWORD shader_code_dp2add[] =  {
5019         0xffff0200,                                                             /* ps_2_0                       */
5020         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
5021
5022         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5023         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
5024
5025         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
5026         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5027         0x0000ffff                                                              /* end                          */
5028     };
5029
5030     /* Test the _sat modifier, too.  Result here should be:
5031      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5032      *      _SAT: ==> 1.0
5033      *   ADD: (1.0 + -0.5) = 0.5
5034      */
5035     static const DWORD shader_code_dp2add_sat[] =  {
5036         0xffff0200,                                                             /* ps_2_0                           */
5037         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
5038
5039         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
5040         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
5041         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5042
5043         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5044         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5045         0x0000ffff                                                              /* end                              */
5046     };
5047
5048     const float quad[] = {
5049         -1.0,   -1.0,   0.1,
5050          1.0,   -1.0,   0.1,
5051         -1.0,    1.0,   0.1,
5052          1.0,    1.0,   0.1
5053     };
5054
5055
5056     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5057     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5058
5059     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5060     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5061
5062     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5063     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5064
5065     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5066     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5067
5068     if (shader_dp2add) {
5069
5070         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5071         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5072
5073         hr = IDirect3DDevice9_BeginScene(device);
5074         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5075         if(SUCCEEDED(hr))
5076         {
5077             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5078             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5079
5080             hr = IDirect3DDevice9_EndScene(device);
5081             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5082         }
5083
5084         color = getPixelColor(device, 360, 240);
5085         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5086                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5087
5088         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5089         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5090
5091         IDirect3DPixelShader9_Release(shader_dp2add);
5092     } else {
5093         skip("dp2add shader creation failed\n");
5094     }
5095
5096     if (shader_dp2add_sat) {
5097
5098         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5099         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5100
5101         hr = IDirect3DDevice9_BeginScene(device);
5102         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5103         if(SUCCEEDED(hr))
5104         {
5105             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5106             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5107
5108             hr = IDirect3DDevice9_EndScene(device);
5109             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5110         }
5111
5112         color = getPixelColor(device, 360, 240);
5113         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5114                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5115
5116         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5117         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5118
5119         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5120     } else {
5121         skip("dp2add shader creation failed\n");
5122     }
5123
5124     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5125     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5126 }
5127
5128 static void cnd_test(IDirect3DDevice9 *device)
5129 {
5130     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5131     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5132     HRESULT hr;
5133     DWORD color;
5134     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5135      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5136      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5137      */
5138     DWORD shader_code_11[] =  {
5139         0xffff0101,                                                                 /* ps_1_1               */
5140         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5141         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5142         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5143         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5144         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5145         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5146         0x0000ffff                                                                  /* end                  */
5147     };
5148     DWORD shader_code_12[] =  {
5149         0xffff0102,                                                                 /* ps_1_2               */
5150         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5151         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5152         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5153         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5154         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5155         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5156         0x0000ffff                                                                  /* end                  */
5157     };
5158     DWORD shader_code_13[] =  {
5159         0xffff0103,                                                                 /* ps_1_3               */
5160         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5161         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5162         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5163         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5164         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5165         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5166         0x0000ffff                                                                  /* end                  */
5167     };
5168     DWORD shader_code_14[] =  {
5169         0xffff0104,                                                                 /* ps_1_3               */
5170         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5171         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5172         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5173         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5174         0x0000ffff                                                                  /* end                  */
5175     };
5176
5177     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5178      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5179      * set by the compiler, it was added manually after compilation. Note that the COISSUE
5180      * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5181      * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5182      * well enough.
5183      *
5184      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5185      * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5186      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5187      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5188      */
5189     DWORD shader_code_11_coissue[] =  {
5190         0xffff0101,                                                             /* ps_1_1                   */
5191         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5192         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5193         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5194         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5195         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5196         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5197         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5198         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5199         /* 0x40000000 = D3DSI_COISSUE */
5200         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5201         0x0000ffff                                                              /* end                      */
5202     };
5203     DWORD shader_code_12_coissue[] =  {
5204         0xffff0102,                                                             /* ps_1_2                   */
5205         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5206         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5207         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5208         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5209         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5210         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5211         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5212         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5213         /* 0x40000000 = D3DSI_COISSUE */
5214         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5215         0x0000ffff                                                              /* end                      */
5216     };
5217     DWORD shader_code_13_coissue[] =  {
5218         0xffff0103,                                                             /* ps_1_3                   */
5219         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5220         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5221         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5222         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5223         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5224         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5225         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5226         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5227         /* 0x40000000 = D3DSI_COISSUE */
5228         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5229         0x0000ffff                                                              /* end                      */
5230     };
5231     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5232      * compare against 0.5
5233      */
5234     DWORD shader_code_14_coissue[] =  {
5235         0xffff0104,                                                             /* ps_1_4                   */
5236         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5237         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5238         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5239         /* 0x40000000 = D3DSI_COISSUE */
5240         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5241         0x0000ffff                                                              /* end                      */
5242     };
5243     float quad1[] = {
5244         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5245          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5246         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5247          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5248     };
5249     float quad2[] = {
5250          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5251          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5252          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5253          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5254     };
5255     float quad3[] = {
5256          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5257          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5258          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5259          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5260     };
5261     float quad4[] = {
5262         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5263          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5264         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5265          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5266     };
5267     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5268     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5269     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5270     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5271
5272     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5273     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5274
5275     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5276     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5277     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5278     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5279     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5280     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5281     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5282     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5283     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5284     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5285     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5286     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5287     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5288     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5289     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5290     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5291
5292     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5293     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5294     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5295     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5296     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5297     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5298
5299     hr = IDirect3DDevice9_BeginScene(device);
5300     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5301     if(SUCCEEDED(hr))
5302     {
5303         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5304         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5305         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5306         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5307
5308         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5309         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5310         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5311         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5312
5313         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5314         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5315         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5316         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5317
5318         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5319         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5320         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5321         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5322
5323         hr = IDirect3DDevice9_EndScene(device);
5324         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5325     }
5326
5327     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5328     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5329
5330     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5331     color = getPixelColor(device, 158, 118);
5332     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5333     color = getPixelColor(device, 162, 118);
5334     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5335     color = getPixelColor(device, 158, 122);
5336     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5337     color = getPixelColor(device, 162, 122);
5338     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5339
5340     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5341     color = getPixelColor(device, 158, 358);
5342     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5343     color = getPixelColor(device, 162, 358);
5344     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5345         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5346     color = getPixelColor(device, 158, 362);
5347     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5348     color = getPixelColor(device, 162, 362);
5349     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5350         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5351
5352     /* 1.2 shader */
5353     color = getPixelColor(device, 478, 358);
5354     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5355     color = getPixelColor(device, 482, 358);
5356     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5357         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5358     color = getPixelColor(device, 478, 362);
5359     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5360     color = getPixelColor(device, 482, 362);
5361     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5362         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5363
5364     /* 1.3 shader */
5365     color = getPixelColor(device, 478, 118);
5366     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5367     color = getPixelColor(device, 482, 118);
5368     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5369         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5370     color = getPixelColor(device, 478, 122);
5371     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5372     color = getPixelColor(device, 482, 122);
5373     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5374         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5375
5376     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5377     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5378
5379     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5380     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5381     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5382     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5383     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5384     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5385
5386     hr = IDirect3DDevice9_BeginScene(device);
5387     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5388     if(SUCCEEDED(hr))
5389     {
5390         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5391         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5392         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5393         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5394
5395         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5396         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5397         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5398         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5399
5400         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5401         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5402         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5403         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5404
5405         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5406         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5407         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5408         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5409
5410         hr = IDirect3DDevice9_EndScene(device);
5411         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5412     }
5413
5414     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5415     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5416
5417     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5418      * that we swapped the values in c1 and c2 to make the other tests return some color
5419      */
5420     color = getPixelColor(device, 158, 118);
5421     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5422     color = getPixelColor(device, 162, 118);
5423     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5424     color = getPixelColor(device, 158, 122);
5425     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5426     color = getPixelColor(device, 162, 122);
5427     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5428
5429     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5430      * (The Win7 nvidia driver always selects c2)
5431      */
5432     color = getPixelColor(device, 158, 358);
5433     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5434         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5435     color = getPixelColor(device, 162, 358);
5436     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5437         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5438     color = getPixelColor(device, 158, 362);
5439     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5440         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5441     color = getPixelColor(device, 162, 362);
5442     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5443         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5444
5445     /* 1.2 shader */
5446     color = getPixelColor(device, 478, 358);
5447     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5448         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5449     color = getPixelColor(device, 482, 358);
5450     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5451         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5452     color = getPixelColor(device, 478, 362);
5453     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5454         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5455     color = getPixelColor(device, 482, 362);
5456     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5457         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5458
5459     /* 1.3 shader */
5460     color = getPixelColor(device, 478, 118);
5461     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5462         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5463     color = getPixelColor(device, 482, 118);
5464     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5465         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5466     color = getPixelColor(device, 478, 122);
5467     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5468         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5469     color = getPixelColor(device, 482, 122);
5470     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5471         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5472
5473     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5474     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5475
5476     IDirect3DPixelShader9_Release(shader_14_coissue);
5477     IDirect3DPixelShader9_Release(shader_13_coissue);
5478     IDirect3DPixelShader9_Release(shader_12_coissue);
5479     IDirect3DPixelShader9_Release(shader_11_coissue);
5480     IDirect3DPixelShader9_Release(shader_14);
5481     IDirect3DPixelShader9_Release(shader_13);
5482     IDirect3DPixelShader9_Release(shader_12);
5483     IDirect3DPixelShader9_Release(shader_11);
5484 }
5485
5486 static void nested_loop_test(IDirect3DDevice9 *device) {
5487     const DWORD shader_code[] = {
5488         0xffff0300,                                                             /* ps_3_0               */
5489         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5490         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5491         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5492         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5493         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5494         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5495         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5496         0x0000001d,                                                             /* endloop              */
5497         0x0000001d,                                                             /* endloop              */
5498         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5499         0x0000ffff                                                              /* end                  */
5500     };
5501     const DWORD vshader_code[] = {
5502         0xfffe0300,                                                             /* vs_3_0               */
5503         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
5504         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
5505         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
5506         0x0000ffff                                                              /* end                  */
5507     };
5508     IDirect3DPixelShader9 *shader;
5509     IDirect3DVertexShader9 *vshader;
5510     HRESULT hr;
5511     DWORD color;
5512     const float quad[] = {
5513         -1.0,   -1.0,   0.1,
5514          1.0,   -1.0,   0.1,
5515         -1.0,    1.0,   0.1,
5516          1.0,    1.0,   0.1
5517     };
5518
5519     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5520     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5521     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5522     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5523     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5524     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5525     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5526     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5527     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5528     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5529     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5530     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5531
5532     hr = IDirect3DDevice9_BeginScene(device);
5533     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5534     if(SUCCEEDED(hr))
5535     {
5536         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5537         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5538         hr = IDirect3DDevice9_EndScene(device);
5539         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5540     }
5541
5542     color = getPixelColor(device, 360, 240);
5543     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5544        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5545
5546     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5547     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5548
5549     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5550     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5551     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5552     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5553     IDirect3DPixelShader9_Release(shader);
5554     IDirect3DVertexShader9_Release(vshader);
5555 }
5556
5557 struct varying_test_struct
5558 {
5559     const DWORD             *shader_code;
5560     IDirect3DPixelShader9   *shader;
5561     DWORD                   color, color_rhw;
5562     const char              *name;
5563     BOOL                    todo, todo_rhw;
5564 };
5565
5566 struct hugeVertex
5567 {
5568     float pos_x,        pos_y,      pos_z,      rhw;
5569     float weight_1,     weight_2,   weight_3,   weight_4;
5570     float index_1,      index_2,    index_3,    index_4;
5571     float normal_1,     normal_2,   normal_3,   normal_4;
5572     float fog_1,        fog_2,      fog_3,      fog_4;
5573     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5574     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5575     float binormal_1,   binormal_2, binormal_3, binormal_4;
5576     float depth_1,      depth_2,    depth_3,    depth_4;
5577     DWORD diffuse, specular;
5578 };
5579
5580 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5581     /* dcl_position: fails to compile */
5582     const DWORD blendweight_code[] = {
5583         0xffff0300,                             /* ps_3_0                   */
5584         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5585         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5586         0x0000ffff                              /* end                      */
5587     };
5588     const DWORD blendindices_code[] = {
5589         0xffff0300,                             /* ps_3_0                   */
5590         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5591         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5592         0x0000ffff                              /* end                      */
5593     };
5594     const DWORD normal_code[] = {
5595         0xffff0300,                             /* ps_3_0                   */
5596         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5597         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5598         0x0000ffff                              /* end                      */
5599     };
5600     /* psize: fails? */
5601     const DWORD texcoord0_code[] = {
5602         0xffff0300,                             /* ps_3_0                   */
5603         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5604         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5605         0x0000ffff                              /* end                      */
5606     };
5607     const DWORD tangent_code[] = {
5608         0xffff0300,                             /* ps_3_0                   */
5609         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5610         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5611         0x0000ffff                              /* end                      */
5612     };
5613     const DWORD binormal_code[] = {
5614         0xffff0300,                             /* ps_3_0                   */
5615         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5616         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5617         0x0000ffff                              /* end                      */
5618     };
5619     /* tessfactor: fails */
5620     /* positiont: fails */
5621     const DWORD color_code[] = {
5622         0xffff0300,                             /* ps_3_0                   */
5623         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5624         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5625         0x0000ffff                              /* end                      */
5626     };
5627     const DWORD fog_code[] = {
5628         0xffff0300,                             /* ps_3_0                   */
5629         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5630         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5631         0x0000ffff                              /* end                      */
5632     };
5633     const DWORD depth_code[] = {
5634         0xffff0300,                             /* ps_3_0                   */
5635         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5636         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5637         0x0000ffff                              /* end                      */
5638     };
5639     const DWORD specular_code[] = {
5640         0xffff0300,                             /* ps_3_0                   */
5641         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5642         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5643         0x0000ffff                              /* end                      */
5644     };
5645     /* sample: fails */
5646
5647     struct varying_test_struct tests[] = {
5648        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5649        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5650        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5651        /* Why does dx not forward the texcoord? */
5652        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5653        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5654        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5655        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5656        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5657        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5658        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5659     };
5660     /* Declare a monster vertex type :-) */
5661     static const D3DVERTEXELEMENT9 decl_elements[] = {
5662         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5663         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5664         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5665         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5666         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5667         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5668         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5669         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5670         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5671         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5672         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5673         D3DDECL_END()
5674     };
5675     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5676         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5677         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5678         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5679         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5680         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5681         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5682         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5683         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5684         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5685         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5686         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5687         D3DDECL_END()
5688     };
5689     struct hugeVertex data[4] = {
5690         {
5691             -1.0,   -1.0,   0.1,    1.0,
5692              0.1,    0.1,   0.1,    0.1,
5693              0.2,    0.2,   0.2,    0.2,
5694              0.3,    0.3,   0.3,    0.3,
5695              0.4,    0.4,   0.4,    0.4,
5696              0.50,   0.55,  0.55,   0.55,
5697              0.6,    0.6,   0.6,    0.7,
5698              0.7,    0.7,   0.7,    0.6,
5699              0.8,    0.8,   0.8,    0.8,
5700              0xe6e6e6e6, /* 0.9 * 256 */
5701              0x224488ff  /* Nothing special */
5702         },
5703         {
5704              1.0,   -1.0,   0.1,    1.0,
5705              0.1,    0.1,   0.1,    0.1,
5706              0.2,    0.2,   0.2,    0.2,
5707              0.3,    0.3,   0.3,    0.3,
5708              0.4,    0.4,   0.4,    0.4,
5709              0.50,   0.55,  0.55,   0.55,
5710              0.6,    0.6,   0.6,    0.7,
5711              0.7,    0.7,   0.7,    0.6,
5712              0.8,    0.8,   0.8,    0.8,
5713              0xe6e6e6e6, /* 0.9 * 256 */
5714              0x224488ff /* Nothing special */
5715         },
5716         {
5717             -1.0,    1.0,   0.1,    1.0,
5718              0.1,    0.1,   0.1,    0.1,
5719              0.2,    0.2,   0.2,    0.2,
5720              0.3,    0.3,   0.3,    0.3,
5721              0.4,    0.4,   0.4,    0.4,
5722              0.50,   0.55,  0.55,   0.55,
5723              0.6,    0.6,   0.6,    0.7,
5724              0.7,    0.7,   0.7,    0.6,
5725              0.8,    0.8,   0.8,    0.8,
5726              0xe6e6e6e6, /* 0.9 * 256 */
5727              0x224488ff /* Nothing special */
5728         },
5729         {
5730              1.0,    1.0,   0.1,    1.0,
5731              0.1,    0.1,   0.1,    0.1,
5732              0.2,    0.2,   0.2,    0.2,
5733              0.3,    0.3,   0.3,    0.3,
5734              0.4,    0.4,   0.4,    0.4,
5735              0.50,   0.55,  0.55,   0.55,
5736              0.6,    0.6,   0.6,    0.7,
5737              0.7,    0.7,   0.7,    0.6,
5738              0.8,    0.8,   0.8,    0.8,
5739              0xe6e6e6e6, /* 0.9 * 256 */
5740              0x224488ff /* Nothing special */
5741         },
5742     };
5743     struct hugeVertex data2[4];
5744     IDirect3DVertexDeclaration9 *decl;
5745     IDirect3DVertexDeclaration9 *decl2;
5746     HRESULT hr;
5747     unsigned int i;
5748     DWORD color, r, g, b, r_e, g_e, b_e;
5749     BOOL drawok;
5750
5751     memcpy(data2, data, sizeof(data2));
5752     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5753     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5754     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5755     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5756
5757     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5758     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5759     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5760     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5761     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5762     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5763
5764     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5765     {
5766         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5767         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5768            tests[i].name, hr);
5769     }
5770
5771     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5772     {
5773         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5774         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5775
5776         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5777         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5778
5779         hr = IDirect3DDevice9_BeginScene(device);
5780         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5781         drawok = FALSE;
5782         if(SUCCEEDED(hr))
5783         {
5784             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5785             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5786             drawok = SUCCEEDED(hr);
5787             hr = IDirect3DDevice9_EndScene(device);
5788             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5789         }
5790
5791         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5792          * the failure and do not check the color if it failed
5793          */
5794         if(!drawok) {
5795             continue;
5796         }
5797
5798         color = getPixelColor(device, 360, 240);
5799         r = color & 0x00ff0000 >> 16;
5800         g = color & 0x0000ff00 >>  8;
5801         b = color & 0x000000ff;
5802         r_e = tests[i].color & 0x00ff0000 >> 16;
5803         g_e = tests[i].color & 0x0000ff00 >>  8;
5804         b_e = tests[i].color & 0x000000ff;
5805
5806         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5807         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5808
5809         if(tests[i].todo) {
5810             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5811                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5812                          tests[i].name, color, tests[i].color);
5813         } else {
5814             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5815                "Test %s returned color 0x%08x, expected 0x%08x\n",
5816                tests[i].name, color, tests[i].color);
5817         }
5818     }
5819
5820     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5821     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5822     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5823     {
5824         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5825         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5826
5827         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5828         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5829
5830         hr = IDirect3DDevice9_BeginScene(device);
5831         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5832         if(SUCCEEDED(hr))
5833         {
5834             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5835             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5836             hr = IDirect3DDevice9_EndScene(device);
5837             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5838         }
5839
5840         color = getPixelColor(device, 360, 240);
5841         r = color & 0x00ff0000 >> 16;
5842         g = color & 0x0000ff00 >>  8;
5843         b = color & 0x000000ff;
5844         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5845         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5846         b_e = tests[i].color_rhw & 0x000000ff;
5847
5848         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5849         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5850
5851         if(tests[i].todo_rhw) {
5852             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5853              * pipeline
5854              */
5855             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5856                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5857                          tests[i].name, color, tests[i].color_rhw);
5858         } else {
5859             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5860                "Test %s returned color 0x%08x, expected 0x%08x\n",
5861                tests[i].name, color, tests[i].color_rhw);
5862         }
5863     }
5864
5865     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5866     {
5867         IDirect3DPixelShader9_Release(tests[i].shader);
5868     }
5869
5870     IDirect3DVertexDeclaration9_Release(decl2);
5871     IDirect3DVertexDeclaration9_Release(decl);
5872 }
5873
5874 static void test_compare_instructions(IDirect3DDevice9 *device)
5875 {
5876     DWORD shader_sge_vec_code[] = {
5877         0xfffe0101,                                         /* vs_1_1                   */
5878         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5879         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5880         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5881         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5882         0x0000ffff                                          /* end                      */
5883     };
5884     DWORD shader_slt_vec_code[] = {
5885         0xfffe0101,                                         /* vs_1_1                   */
5886         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5887         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5888         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5889         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5890         0x0000ffff                                          /* end                      */
5891     };
5892     DWORD shader_sge_scalar_code[] = {
5893         0xfffe0101,                                         /* vs_1_1                   */
5894         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5895         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5896         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5897         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5898         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5899         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5900         0x0000ffff                                          /* end                      */
5901     };
5902     DWORD shader_slt_scalar_code[] = {
5903         0xfffe0101,                                         /* vs_1_1                   */
5904         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5905         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5906         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5907         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5908         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5909         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5910         0x0000ffff                                          /* end                      */
5911     };
5912     IDirect3DVertexShader9 *shader_sge_vec;
5913     IDirect3DVertexShader9 *shader_slt_vec;
5914     IDirect3DVertexShader9 *shader_sge_scalar;
5915     IDirect3DVertexShader9 *shader_slt_scalar;
5916     HRESULT hr, color;
5917     float quad1[] =  {
5918         -1.0,   -1.0,   0.1,
5919          0.0,   -1.0,   0.1,
5920         -1.0,    0.0,   0.1,
5921          0.0,    0.0,   0.1
5922     };
5923     float quad2[] =  {
5924          0.0,   -1.0,   0.1,
5925          1.0,   -1.0,   0.1,
5926          0.0,    0.0,   0.1,
5927          1.0,    0.0,   0.1
5928     };
5929     float quad3[] =  {
5930         -1.0,    0.0,   0.1,
5931          0.0,    0.0,   0.1,
5932         -1.0,    1.0,   0.1,
5933          0.0,    1.0,   0.1
5934     };
5935     float quad4[] =  {
5936          0.0,    0.0,   0.1,
5937          1.0,    0.0,   0.1,
5938          0.0,    1.0,   0.1,
5939          1.0,    1.0,   0.1
5940     };
5941     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5942     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5943
5944     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5945     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5946
5947     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5948     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5949     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5950     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5951     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5952     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5953     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5954     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5955     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5956     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5957     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5958     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5959     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5960     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5961
5962     hr = IDirect3DDevice9_BeginScene(device);
5963     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5964     if(SUCCEEDED(hr))
5965     {
5966         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5967         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5968         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5969         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5970
5971         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5972         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5973         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5974         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5975
5976         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5977         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5978         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5979         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5980
5981         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5982         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5983
5984         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5985         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5986         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5987         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5988
5989         hr = IDirect3DDevice9_EndScene(device);
5990         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5991     }
5992
5993     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5994     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5995
5996     color = getPixelColor(device, 160, 360);
5997     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5998     color = getPixelColor(device, 480, 360);
5999     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6000     color = getPixelColor(device, 160, 120);
6001     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6002     color = getPixelColor(device, 480, 160);
6003     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6004
6005     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6006     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6007
6008     IDirect3DVertexShader9_Release(shader_sge_vec);
6009     IDirect3DVertexShader9_Release(shader_slt_vec);
6010     IDirect3DVertexShader9_Release(shader_sge_scalar);
6011     IDirect3DVertexShader9_Release(shader_slt_scalar);
6012 }
6013
6014 static void test_vshader_input(IDirect3DDevice9 *device)
6015 {
6016     DWORD swapped_shader_code_3[] = {
6017         0xfffe0300,                                         /* vs_3_0               */
6018         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6019         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6020         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6021         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6022         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6023         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6024         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6025         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6026         0x0000ffff                                          /* end                  */
6027     };
6028     DWORD swapped_shader_code_1[] = {
6029         0xfffe0101,                                         /* vs_1_1               */
6030         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6031         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6032         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6033         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6034         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6035         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6036         0x0000ffff                                          /* end                  */
6037     };
6038     DWORD swapped_shader_code_2[] = {
6039         0xfffe0200,                                         /* vs_2_0               */
6040         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6041         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6042         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6043         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6044         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6045         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6046         0x0000ffff                                          /* end                  */
6047     };
6048     DWORD texcoord_color_shader_code_3[] = {
6049         0xfffe0300,                                         /* vs_3_0               */
6050         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6051         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6052         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6053         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6054         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6055         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6056         0x0000ffff                                          /* end                  */
6057     };
6058     DWORD texcoord_color_shader_code_2[] = {
6059         0xfffe0200,                                         /* vs_2_0               */
6060         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6061         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6062         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6063         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6064         0x0000ffff                                          /* end                  */
6065     };
6066     DWORD texcoord_color_shader_code_1[] = {
6067         0xfffe0101,                                         /* vs_1_1               */
6068         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6069         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6070         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6071         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6072         0x0000ffff                                          /* end                  */
6073     };
6074     DWORD color_color_shader_code_3[] = {
6075         0xfffe0300,                                         /* vs_3_0               */
6076         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6077         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6078         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6079         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6080         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6081         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6082         0x0000ffff                                          /* end                  */
6083     };
6084     DWORD color_color_shader_code_2[] = {
6085         0xfffe0200,                                         /* vs_2_0               */
6086         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6087         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6088         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6089         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6090         0x0000ffff                                          /* end                  */
6091     };
6092     DWORD color_color_shader_code_1[] = {
6093         0xfffe0101,                                         /* vs_1_1               */
6094         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6095         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6096         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6097         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6098         0x0000ffff                                          /* end                  */
6099     };
6100     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6101     HRESULT hr;
6102     DWORD color;
6103     float quad1[] =  {
6104         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6105          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6106         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6107          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6108     };
6109     float quad2[] =  {
6110          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6111          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6112          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6113          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6114     };
6115     float quad3[] =  {
6116         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6117          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6118         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6119          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6120     };
6121     float quad4[] =  {
6122          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6123          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6124          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6125          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6126     };
6127     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6128         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6129         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6130         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6131         D3DDECL_END()
6132     };
6133     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6134         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6135         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6136         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6137         D3DDECL_END()
6138     };
6139     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6140         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6141         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6142         D3DDECL_END()
6143     };
6144     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6145         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6146         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6147         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6148         D3DDECL_END()
6149     };
6150     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6151         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6152         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6153         D3DDECL_END()
6154     };
6155     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6156         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6157         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6158         D3DDECL_END()
6159     };
6160     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6161         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6162         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6163         D3DDECL_END()
6164     };
6165     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6166         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6167         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6168         D3DDECL_END()
6169     };
6170     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6171     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6172     unsigned int i;
6173     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6174     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6175
6176     struct vertex quad1_color[] =  {
6177        {-1.0,   -1.0,   0.1,    0x00ff8040},
6178        { 0.0,   -1.0,   0.1,    0x00ff8040},
6179        {-1.0,    0.0,   0.1,    0x00ff8040},
6180        { 0.0,    0.0,   0.1,    0x00ff8040}
6181     };
6182     struct vertex quad2_color[] =  {
6183        { 0.0,   -1.0,   0.1,    0x00ff8040},
6184        { 1.0,   -1.0,   0.1,    0x00ff8040},
6185        { 0.0,    0.0,   0.1,    0x00ff8040},
6186        { 1.0,    0.0,   0.1,    0x00ff8040}
6187     };
6188     struct vertex quad3_color[] =  {
6189        {-1.0,    0.0,   0.1,    0x00ff8040},
6190        { 0.0,    0.0,   0.1,    0x00ff8040},
6191        {-1.0,    1.0,   0.1,    0x00ff8040},
6192        { 0.0,    1.0,   0.1,    0x00ff8040}
6193     };
6194     float quad4_color[] =  {
6195          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6196          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6197          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6198          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6199     };
6200
6201     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6202     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6203     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6204     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6205     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6206     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6207     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6208     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6209
6210     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6211     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6212     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6213     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6214     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6215     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6216     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6217     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6218
6219     for(i = 1; i <= 3; i++) {
6220         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6221         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6222         if(i == 3) {
6223             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6224             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6225         } else if(i == 2){
6226             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6227             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6228         } else if(i == 1) {
6229             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6230             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6231         }
6232
6233         hr = IDirect3DDevice9_BeginScene(device);
6234         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6235         if(SUCCEEDED(hr))
6236         {
6237             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6238             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6239
6240             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6241             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6242             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6243             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6244
6245             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6246             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6247             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6248             if(i == 3 || i == 2) {
6249                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6250             } else if(i == 1) {
6251                 /* Succeeds or fails, depending on SW or HW vertex processing */
6252                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6253             }
6254
6255             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6256             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6257             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6258             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6259
6260             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6261             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6262             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6263             if(i == 3 || i == 2) {
6264                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6265             } else if(i == 1) {
6266                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6267             }
6268
6269             hr = IDirect3DDevice9_EndScene(device);
6270             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6271         }
6272
6273         if(i == 3 || i == 2) {
6274             color = getPixelColor(device, 160, 360);
6275             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6276                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6277
6278             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6279             color = getPixelColor(device, 480, 360);
6280             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6281                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6282             color = getPixelColor(device, 160, 120);
6283             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6284             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6285                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6286
6287             color = getPixelColor(device, 480, 160);
6288             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6289         } else if(i == 1) {
6290             color = getPixelColor(device, 160, 360);
6291             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6292                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6293             color = getPixelColor(device, 480, 360);
6294             /* Accept the clear color as well in this case, since SW VP returns an error */
6295             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6296             color = getPixelColor(device, 160, 120);
6297             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6298                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6299             color = getPixelColor(device, 480, 160);
6300             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6301         }
6302
6303         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6304         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6305
6306         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6307         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6308
6309         /* Now find out if the whole streams are re-read, or just the last active value for the
6310          * vertices is used.
6311          */
6312         hr = IDirect3DDevice9_BeginScene(device);
6313         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6314         if(SUCCEEDED(hr))
6315         {
6316             float quad1_modified[] =  {
6317                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6318                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6319                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6320                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6321             };
6322             float quad2_modified[] =  {
6323                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6324                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6325                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6326                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6327             };
6328
6329             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6330             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6331
6332             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6333             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6334             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6335             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6336
6337             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6338             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6339             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6340             if(i == 3 || i == 2) {
6341                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6342             } else if(i == 1) {
6343                 /* Succeeds or fails, depending on SW or HW vertex processing */
6344                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6345             }
6346
6347             hr = IDirect3DDevice9_EndScene(device);
6348             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6349         }
6350
6351         color = getPixelColor(device, 480, 350);
6352         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6353          * as well.
6354          *
6355          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6356          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6357          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6358          * refrast's result.
6359          *
6360          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6361          */
6362         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6363            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6364
6365         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6366         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6367
6368         IDirect3DDevice9_SetVertexShader(device, NULL);
6369         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6370
6371         IDirect3DVertexShader9_Release(swapped_shader);
6372     }
6373
6374     for(i = 1; i <= 3; i++) {
6375         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6376         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6377         if(i == 3) {
6378             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6379             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6380             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6381             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6382         } else if(i == 2){
6383             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6384             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6385             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6386             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6387         } else if(i == 1) {
6388             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6389             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6390             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6391             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6392         }
6393
6394         hr = IDirect3DDevice9_BeginScene(device);
6395         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6396         if(SUCCEEDED(hr))
6397         {
6398             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6399             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6400             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6401             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6402             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6403             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6404
6405             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6406             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6407
6408             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6409             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6410             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6411             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6412             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6413             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6414
6415             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6416             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6417             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6418             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6419             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6420             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6421
6422             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6423             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6424             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6425             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6426
6427             hr = IDirect3DDevice9_EndScene(device);
6428             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6429         }
6430         IDirect3DDevice9_SetVertexShader(device, NULL);
6431         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6432
6433         color = getPixelColor(device, 160, 360);
6434         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6435            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6436         color = getPixelColor(device, 480, 360);
6437         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6438            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6439         color = getPixelColor(device, 160, 120);
6440         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6441            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6442         color = getPixelColor(device, 480, 160);
6443         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6444            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6445
6446         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6447         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6448
6449         IDirect3DVertexShader9_Release(texcoord_color_shader);
6450         IDirect3DVertexShader9_Release(color_color_shader);
6451     }
6452
6453     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6454     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6455     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6456     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6457
6458     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6459     IDirect3DVertexDeclaration9_Release(decl_color_color);
6460     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6461     IDirect3DVertexDeclaration9_Release(decl_color_float);
6462 }
6463
6464 static void srgbtexture_test(IDirect3DDevice9 *device)
6465 {
6466     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6467      * texture stage state to render a quad using that texture.  The resulting
6468      * color components should be 0x36 (~ 0.21), per this formula:
6469      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6470      * This is true where srgb_color > 0.04045.
6471      */
6472     IDirect3D9 *d3d = NULL;
6473     HRESULT hr;
6474     LPDIRECT3DTEXTURE9 texture = NULL;
6475     LPDIRECT3DSURFACE9 surface = NULL;
6476     D3DLOCKED_RECT lr;
6477     DWORD color;
6478     float quad[] = {
6479         -1.0,       1.0,       0.0,     0.0,    0.0,
6480          1.0,       1.0,       0.0,     1.0,    0.0,
6481         -1.0,      -1.0,       0.0,     0.0,    1.0,
6482          1.0,      -1.0,       0.0,     1.0,    1.0,
6483     };
6484
6485
6486     memset(&lr, 0, sizeof(lr));
6487     IDirect3DDevice9_GetDirect3D(device, &d3d);
6488     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6489                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6490                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6491         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6492         goto out;
6493     }
6494
6495     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6496                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6497                                         &texture, NULL);
6498     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6499     if(!texture) {
6500         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6501         goto out;
6502     }
6503     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6504     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6505
6506     fill_surface(surface, 0xff7f7f7f);
6507     IDirect3DSurface9_Release(surface);
6508
6509     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6510     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6511     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6512     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6513
6514     hr = IDirect3DDevice9_BeginScene(device);
6515     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6516     if(SUCCEEDED(hr))
6517     {
6518         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6519         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6520
6521         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6522         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6523
6524
6525         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6526         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6527
6528         hr = IDirect3DDevice9_EndScene(device);
6529         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6530     }
6531
6532     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6533     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6534     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6535     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6536
6537     color = getPixelColor(device, 320, 240);
6538     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6539
6540     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6541     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6542
6543 out:
6544     if(texture) IDirect3DTexture9_Release(texture);
6545     IDirect3D9_Release(d3d);
6546 }
6547
6548 static void shademode_test(IDirect3DDevice9 *device)
6549 {
6550     /* Render a quad and try all of the different fixed function shading models. */
6551     HRESULT hr;
6552     DWORD color0, color1;
6553     DWORD color0_gouraud = 0, color1_gouraud = 0;
6554     DWORD shademode = D3DSHADE_FLAT;
6555     DWORD primtype = D3DPT_TRIANGLESTRIP;
6556     LPVOID data = NULL;
6557     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6558     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6559     UINT i, j;
6560     struct vertex quad_strip[] =
6561     {
6562         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6563         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6564         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6565         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6566     };
6567     struct vertex quad_list[] =
6568     {
6569         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6570         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6571         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6572
6573         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6574         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6575         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6576     };
6577
6578     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6579                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6580     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6581     if (FAILED(hr)) goto bail;
6582
6583     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6584                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6585     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6586     if (FAILED(hr)) goto bail;
6587
6588     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6589     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6590
6591     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6592     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6593
6594     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6595     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6596     memcpy(data, quad_strip, sizeof(quad_strip));
6597     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6598     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6599
6600     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6601     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6602     memcpy(data, quad_list, sizeof(quad_list));
6603     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6604     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6605
6606     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6607      * the color fixups we have to do for FLAT shading will be dependent on that. */
6608     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6609     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6610
6611     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6612     for (j=0; j<2; j++) {
6613
6614         /* Inner loop just changes the D3DRS_SHADEMODE */
6615         for (i=0; i<3; i++) {
6616             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6617             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6618
6619             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6620             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6621
6622             hr = IDirect3DDevice9_BeginScene(device);
6623             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6624             if(SUCCEEDED(hr))
6625             {
6626                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6627                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6628
6629                 hr = IDirect3DDevice9_EndScene(device);
6630                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6631             }
6632
6633             /* Sample two spots from the output */
6634             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6635             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6636             switch(shademode) {
6637                 case D3DSHADE_FLAT:
6638                     /* Should take the color of the first vertex of each triangle */
6639                     if (0)
6640                     {
6641                         /* This test depends on EXT_provoking_vertex being
6642                          * available. This extension is currently (20090810)
6643                          * not common enough to let the test fail if it isn't
6644                          * present. */
6645                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6646                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6647                     }
6648                     shademode = D3DSHADE_GOURAUD;
6649                     break;
6650                 case D3DSHADE_GOURAUD:
6651                     /* Should be an interpolated blend */
6652
6653                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6654                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6655                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6656                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6657
6658                     color0_gouraud = color0;
6659                     color1_gouraud = color1;
6660
6661                     shademode = D3DSHADE_PHONG;
6662                     break;
6663                 case D3DSHADE_PHONG:
6664                     /* Should be the same as GOURAUD, since no hardware implements this */
6665                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6666                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6667                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6668                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6669
6670                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6671                             color0_gouraud, color0);
6672                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6673                             color1_gouraud, color1);
6674                     break;
6675             }
6676         }
6677
6678         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6679         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6680
6681         /* Now, do it all over again with a TRIANGLELIST */
6682         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6683         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6684         primtype = D3DPT_TRIANGLELIST;
6685         shademode = D3DSHADE_FLAT;
6686     }
6687
6688 bail:
6689     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6690     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6691     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6692     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6693
6694     if (vb_strip)
6695         IDirect3DVertexBuffer9_Release(vb_strip);
6696     if (vb_list)
6697         IDirect3DVertexBuffer9_Release(vb_list);
6698 }
6699
6700 static void alpha_test(IDirect3DDevice9 *device)
6701 {
6702     HRESULT hr;
6703     IDirect3DTexture9 *offscreenTexture;
6704     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6705     DWORD color;
6706
6707     struct vertex quad1[] =
6708     {
6709         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6710         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6711         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6712         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6713     };
6714     struct vertex quad2[] =
6715     {
6716         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6717         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6718         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6719         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6720     };
6721     static const float composite_quad[][5] = {
6722         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6723         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6724         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6725         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6726     };
6727
6728     /* Clear the render target with alpha = 0.5 */
6729     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6730     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6731
6732     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6733     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6734
6735     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6736     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6737     if(!backbuffer) {
6738         goto out;
6739     }
6740
6741     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6742     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6743     if(!offscreen) {
6744         goto out;
6745     }
6746
6747     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6748     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6749
6750     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6751     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6752     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6753     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6754     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6755     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6756     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6757     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6758     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6759     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6760
6761     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6762     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6763     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6764
6765         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6766         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6767         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6768         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6769         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6770         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6771         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6772
6773         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6774         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6775         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6776         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6777         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6778         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6779
6780         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6781          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6782          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6783         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6784         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6785         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6786         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6787
6788         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6789         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6790         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6791         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6792         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6793         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6794
6795         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6796         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6797         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6798         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6799         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6800         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6801
6802         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6803         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6804
6805         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6806          * Disable alpha blending for the final composition
6807          */
6808         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6809         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6810         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6811         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6812
6813         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6814         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6815         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6816         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6817         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6818         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6819
6820         hr = IDirect3DDevice9_EndScene(device);
6821         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6822     }
6823
6824     color = getPixelColor(device, 160, 360);
6825     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6826        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6827
6828     color = getPixelColor(device, 160, 120);
6829     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6830        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6831
6832     color = getPixelColor(device, 480, 360);
6833     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6834        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6835
6836     color = getPixelColor(device, 480, 120);
6837     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6838        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6839
6840     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6841
6842     out:
6843     /* restore things */
6844     if(backbuffer) {
6845         IDirect3DSurface9_Release(backbuffer);
6846     }
6847     if(offscreenTexture) {
6848         IDirect3DTexture9_Release(offscreenTexture);
6849     }
6850     if(offscreen) {
6851         IDirect3DSurface9_Release(offscreen);
6852     }
6853 }
6854
6855 struct vertex_shortcolor {
6856     float x, y, z;
6857     unsigned short r, g, b, a;
6858 };
6859 struct vertex_floatcolor {
6860     float x, y, z;
6861     float r, g, b, a;
6862 };
6863
6864 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6865 {
6866     HRESULT hr;
6867     BOOL s_ok, ub_ok, f_ok;
6868     DWORD color, size, i;
6869     void *data;
6870     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6871         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6872         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6873         D3DDECL_END()
6874     };
6875     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6876         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6877         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6878         D3DDECL_END()
6879     };
6880     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6881         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6882         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6883         D3DDECL_END()
6884     };
6885     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6886         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6887         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6888         D3DDECL_END()
6889     };
6890     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6891         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6892         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6893         D3DDECL_END()
6894     };
6895     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6896         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6897         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6898         D3DDECL_END()
6899     };
6900     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6901         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6902         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6903         D3DDECL_END()
6904     };
6905     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6906     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6907     IDirect3DVertexBuffer9 *vb, *vb2;
6908     struct vertex quad1[] =                             /* D3DCOLOR */
6909     {
6910         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6911         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6912         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6913         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6914     };
6915     struct vertex quad2[] =                             /* UBYTE4N */
6916     {
6917         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6918         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6919         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6920         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6921     };
6922     struct vertex_shortcolor quad3[] =                  /* short */
6923     {
6924         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6925         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6926         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6927         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6928     };
6929     struct vertex_floatcolor quad4[] =
6930     {
6931         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6932         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6933         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6934         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6935     };
6936     DWORD colors[] = {
6937         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6938         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6939         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6940         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6941         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6942         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6943         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6944         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6945         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6946         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6947         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6948         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6949         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6950         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6951         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6952         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6953     };
6954     float quads[] = {
6955         -1.0,   -1.0,     0.1,
6956         -1.0,    0.0,     0.1,
6957          0.0,   -1.0,     0.1,
6958          0.0,    0.0,     0.1,
6959
6960          0.0,   -1.0,     0.1,
6961          0.0,    0.0,     0.1,
6962          1.0,   -1.0,     0.1,
6963          1.0,    0.0,     0.1,
6964
6965          0.0,    0.0,     0.1,
6966          0.0,    1.0,     0.1,
6967          1.0,    0.0,     0.1,
6968          1.0,    1.0,     0.1,
6969
6970         -1.0,    0.0,     0.1,
6971         -1.0,    1.0,     0.1,
6972          0.0,    0.0,     0.1,
6973          0.0,    1.0,     0.1
6974     };
6975     struct tvertex quad_transformed[] = {
6976        {  90,    110,     0.1,      2.0,        0x00ffff00},
6977        { 570,    110,     0.1,      2.0,        0x00ffff00},
6978        {  90,    300,     0.1,      2.0,        0x00ffff00},
6979        { 570,    300,     0.1,      2.0,        0x00ffff00}
6980     };
6981     D3DCAPS9 caps;
6982
6983     memset(&caps, 0, sizeof(caps));
6984     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6985     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6986
6987     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6988     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6989
6990     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6991     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6992     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6993     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6994     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6995     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6996     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6997         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6998         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6999         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7000         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7001     } else {
7002         trace("D3DDTCAPS_UBYTE4N not supported\n");
7003         dcl_ubyte_2 = NULL;
7004         dcl_ubyte = NULL;
7005     }
7006     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7007     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7008     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7009     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7010
7011     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7012     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7013                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7014     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7015
7016     hr = IDirect3DDevice9_BeginScene(device);
7017     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7018     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7019     if(SUCCEEDED(hr)) {
7020         if(dcl_color) {
7021             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7022             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7023             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7024             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7025         }
7026
7027         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7028          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7029          * using software vertex processing. Doh!
7030          */
7031         if(dcl_ubyte) {
7032             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7033             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7034             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7035             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7036             ub_ok = SUCCEEDED(hr);
7037         }
7038
7039         if(dcl_short) {
7040             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7041             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7042             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7043             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7044             s_ok = SUCCEEDED(hr);
7045         }
7046
7047         if(dcl_float) {
7048             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7049             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7050             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7051             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7052             f_ok = SUCCEEDED(hr);
7053         }
7054
7055         hr = IDirect3DDevice9_EndScene(device);
7056         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7057     }
7058
7059     if(dcl_short) {
7060         color = getPixelColor(device, 480, 360);
7061         ok(color == 0x000000ff || !s_ok,
7062            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7063     }
7064     if(dcl_ubyte) {
7065         color = getPixelColor(device, 160, 120);
7066         ok(color == 0x0000ffff || !ub_ok,
7067            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7068     }
7069     if(dcl_color) {
7070         color = getPixelColor(device, 160, 360);
7071         ok(color == 0x00ffff00,
7072            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7073     }
7074     if(dcl_float) {
7075         color = getPixelColor(device, 480, 120);
7076         ok(color == 0x00ff0000 || !f_ok,
7077            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7078     }
7079     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7080
7081     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7082      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7083      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7084      * whether the immediate mode code works
7085      */
7086     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7087     hr = IDirect3DDevice9_BeginScene(device);
7088     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7089     if(SUCCEEDED(hr)) {
7090         if(dcl_color) {
7091             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7092             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7093             memcpy(data, quad1, sizeof(quad1));
7094             hr = IDirect3DVertexBuffer9_Unlock(vb);
7095             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7096             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7097             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7098             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7099             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7100             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7101             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7102         }
7103
7104         if(dcl_ubyte) {
7105             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7106             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7107             memcpy(data, quad2, sizeof(quad2));
7108             hr = IDirect3DVertexBuffer9_Unlock(vb);
7109             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7110             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7111             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7112             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7113             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7114             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7115             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7116                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7117             ub_ok = SUCCEEDED(hr);
7118         }
7119
7120         if(dcl_short) {
7121             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7122             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7123             memcpy(data, quad3, sizeof(quad3));
7124             hr = IDirect3DVertexBuffer9_Unlock(vb);
7125             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7126             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7127             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7128             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7129             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7130             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7131             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7132                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7133             s_ok = SUCCEEDED(hr);
7134         }
7135
7136         if(dcl_float) {
7137             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7138             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7139             memcpy(data, quad4, sizeof(quad4));
7140             hr = IDirect3DVertexBuffer9_Unlock(vb);
7141             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7142             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7143             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7144             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7145             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7146             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7147             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7148                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7149             f_ok = SUCCEEDED(hr);
7150         }
7151
7152         hr = IDirect3DDevice9_EndScene(device);
7153         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7154     }
7155
7156     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7157     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7158     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7159     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7160
7161     if(dcl_short) {
7162         color = getPixelColor(device, 480, 360);
7163         ok(color == 0x000000ff || !s_ok,
7164            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7165     }
7166     if(dcl_ubyte) {
7167         color = getPixelColor(device, 160, 120);
7168         ok(color == 0x0000ffff || !ub_ok,
7169            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7170     }
7171     if(dcl_color) {
7172         color = getPixelColor(device, 160, 360);
7173         ok(color == 0x00ffff00,
7174            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7175     }
7176     if(dcl_float) {
7177         color = getPixelColor(device, 480, 120);
7178         ok(color == 0x00ff0000 || !f_ok,
7179            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7180     }
7181     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7182
7183     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7184     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7185
7186     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7187     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7188     memcpy(data, quad_transformed, sizeof(quad_transformed));
7189     hr = IDirect3DVertexBuffer9_Unlock(vb);
7190     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7191
7192     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7193     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7194
7195     hr = IDirect3DDevice9_BeginScene(device);
7196     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7197     if(SUCCEEDED(hr)) {
7198         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7199         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7200         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7201         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7202
7203         hr = IDirect3DDevice9_EndScene(device);
7204         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7205     }
7206
7207     color = getPixelColor(device, 88, 108);
7208     ok(color == 0x000000ff,
7209        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7210     color = getPixelColor(device, 92, 108);
7211     ok(color == 0x000000ff,
7212        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7213     color = getPixelColor(device, 88, 112);
7214     ok(color == 0x000000ff,
7215        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7216     color = getPixelColor(device, 92, 112);
7217     ok(color == 0x00ffff00,
7218        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7219
7220     color = getPixelColor(device, 568, 108);
7221     ok(color == 0x000000ff,
7222        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7223     color = getPixelColor(device, 572, 108);
7224     ok(color == 0x000000ff,
7225        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7226     color = getPixelColor(device, 568, 112);
7227     ok(color == 0x00ffff00,
7228        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7229     color = getPixelColor(device, 572, 112);
7230     ok(color == 0x000000ff,
7231        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7232
7233     color = getPixelColor(device, 88, 298);
7234     ok(color == 0x000000ff,
7235        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7236     color = getPixelColor(device, 92, 298);
7237     ok(color == 0x00ffff00,
7238        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7239     color = getPixelColor(device, 88, 302);
7240     ok(color == 0x000000ff,
7241        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7242     color = getPixelColor(device, 92, 302);
7243     ok(color == 0x000000ff,
7244        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7245
7246     color = getPixelColor(device, 568, 298);
7247     ok(color == 0x00ffff00,
7248        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7249     color = getPixelColor(device, 572, 298);
7250     ok(color == 0x000000ff,
7251        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7252     color = getPixelColor(device, 568, 302);
7253     ok(color == 0x000000ff,
7254        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7255     color = getPixelColor(device, 572, 302);
7256     ok(color == 0x000000ff,
7257        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7258
7259     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7260
7261     /* This test is pointless without those two declarations: */
7262     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7263         skip("color-ubyte switching test declarations aren't supported\n");
7264         goto out;
7265     }
7266
7267     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7268     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7269     memcpy(data, quads, sizeof(quads));
7270     hr = IDirect3DVertexBuffer9_Unlock(vb);
7271     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7272     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7273                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7274     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7275     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7276     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7277     memcpy(data, colors, sizeof(colors));
7278     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7279     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7280
7281     for(i = 0; i < 2; i++) {
7282         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7283         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7284
7285         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7286         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7287         if(i == 0) {
7288             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7289         } else {
7290             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7291         }
7292         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7293
7294         hr = IDirect3DDevice9_BeginScene(device);
7295         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7296         ub_ok = FALSE;
7297         if(SUCCEEDED(hr)) {
7298             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7299             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7300             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7301             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7302                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7303             ub_ok = SUCCEEDED(hr);
7304
7305             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7306             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7307             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7308             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7309
7310             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7311             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7312             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7313             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7314                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7315             ub_ok = (SUCCEEDED(hr) && ub_ok);
7316
7317             hr = IDirect3DDevice9_EndScene(device);
7318             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7319         }
7320
7321         if(i == 0) {
7322             color = getPixelColor(device, 480, 360);
7323             ok(color == 0x00ff0000,
7324                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7325             color = getPixelColor(device, 160, 120);
7326             ok(color == 0x00ffffff,
7327                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7328             color = getPixelColor(device, 160, 360);
7329             ok(color == 0x000000ff || !ub_ok,
7330                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7331             color = getPixelColor(device, 480, 120);
7332             ok(color == 0x000000ff || !ub_ok,
7333                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7334         } else {
7335             color = getPixelColor(device, 480, 360);
7336             ok(color == 0x000000ff,
7337                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7338             color = getPixelColor(device, 160, 120);
7339             ok(color == 0x00ffffff,
7340                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7341             color = getPixelColor(device, 160, 360);
7342             ok(color == 0x00ff0000 || !ub_ok,
7343                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7344             color = getPixelColor(device, 480, 120);
7345             ok(color == 0x00ff0000 || !ub_ok,
7346                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7347         }
7348         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7349     }
7350
7351     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7352     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7353     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7354     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7355     IDirect3DVertexBuffer9_Release(vb2);
7356
7357     out:
7358     IDirect3DVertexBuffer9_Release(vb);
7359     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7360     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7361     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7362     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7363     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7364     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7365     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7366 }
7367
7368 struct vertex_float16color {
7369     float x, y, z;
7370     DWORD c1, c2;
7371 };
7372
7373 static void test_vshader_float16(IDirect3DDevice9 *device)
7374 {
7375     HRESULT hr;
7376     DWORD color;
7377     void *data;
7378     static const D3DVERTEXELEMENT9 decl_elements[] = {
7379         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7380         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7381         D3DDECL_END()
7382     };
7383     IDirect3DVertexDeclaration9 *vdecl = NULL;
7384     IDirect3DVertexBuffer9 *buffer = NULL;
7385     IDirect3DVertexShader9 *shader;
7386     DWORD shader_code[] = {
7387         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7388         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7389         0x90e40001, 0x0000ffff
7390     };
7391     struct vertex_float16color quad[] = {
7392         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7393         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7394         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7395         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7396
7397         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7398         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7399         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7400         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7401
7402         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7403         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7404         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7405         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7406
7407         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7408         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7409         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7410         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7411     };
7412
7413     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7414     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7415
7416     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7417     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7418     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7419     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7420     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7421     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7422
7423     hr = IDirect3DDevice9_BeginScene(device);
7424     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7425     if(SUCCEEDED(hr)) {
7426         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7427         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7428         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7429         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7430         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7431         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7432         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7433         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7434         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7435         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7436
7437         hr = IDirect3DDevice9_EndScene(device);
7438         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7439     }
7440     color = getPixelColor(device, 480, 360);
7441     ok(color == 0x00ff0000,
7442        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7443     color = getPixelColor(device, 160, 120);
7444     ok(color == 0x00000000,
7445        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7446     color = getPixelColor(device, 160, 360);
7447     ok(color == 0x0000ff00,
7448        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7449     color = getPixelColor(device, 480, 120);
7450     ok(color == 0x000000ff,
7451        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7452     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7453
7454     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7455     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7456
7457     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7458                                              D3DPOOL_MANAGED, &buffer, NULL);
7459     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7460     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7461     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7462     memcpy(data, quad, sizeof(quad));
7463     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7464     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7465     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7466     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7467
7468     hr = IDirect3DDevice9_BeginScene(device);
7469     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7470     if(SUCCEEDED(hr)) {
7471             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7472             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7473             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7474             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7475             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7476             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7477             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7478             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7479
7480             hr = IDirect3DDevice9_EndScene(device);
7481             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7482     }
7483
7484     color = getPixelColor(device, 480, 360);
7485     ok(color == 0x00ff0000,
7486        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7487     color = getPixelColor(device, 160, 120);
7488     ok(color == 0x00000000,
7489        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7490     color = getPixelColor(device, 160, 360);
7491     ok(color == 0x0000ff00,
7492        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7493     color = getPixelColor(device, 480, 120);
7494     ok(color == 0x000000ff,
7495        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7496     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7497
7498     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7499     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7500     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7501     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7502     IDirect3DDevice9_SetVertexShader(device, NULL);
7503     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7504
7505     IDirect3DVertexDeclaration9_Release(vdecl);
7506     IDirect3DVertexShader9_Release(shader);
7507     IDirect3DVertexBuffer9_Release(buffer);
7508 }
7509
7510 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7511 {
7512     D3DCAPS9 caps;
7513     IDirect3DTexture9 *texture;
7514     HRESULT hr;
7515     D3DLOCKED_RECT rect;
7516     unsigned int x, y;
7517     DWORD *dst, color;
7518     const float quad[] = {
7519         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7520          1.0,   -1.0,   0.1,    1.2,   -0.2,
7521         -1.0,    1.0,   0.1,   -0.2,    1.2,
7522          1.0,    1.0,   0.1,    1.2,    1.2
7523     };
7524     memset(&caps, 0, sizeof(caps));
7525
7526     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7527     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7528     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7529         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7530         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7531            "Card has conditional NP2 support without power of two restriction set\n");
7532         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7533         return;
7534     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7535         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7536         return;
7537     }
7538
7539     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7540     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7541
7542     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7543     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7544
7545     memset(&rect, 0, sizeof(rect));
7546     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7547     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7548     for(y = 0; y < 10; y++) {
7549         for(x = 0; x < 10; x++) {
7550             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7551             if(x == 0 || x == 9 || y == 0 || y == 9) {
7552                 *dst = 0x00ff0000;
7553             } else {
7554                 *dst = 0x000000ff;
7555             }
7556         }
7557     }
7558     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7559     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7560
7561     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7562     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7563     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7564     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7565     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7566     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7567     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7568     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7569
7570     hr = IDirect3DDevice9_BeginScene(device);
7571     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7572     if(SUCCEEDED(hr)) {
7573         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7574         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7575
7576         hr = IDirect3DDevice9_EndScene(device);
7577         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7578     }
7579
7580     color = getPixelColor(device,    1,  1);
7581     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7582     color = getPixelColor(device, 639, 479);
7583     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7584
7585     color = getPixelColor(device, 135, 101);
7586     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7587     color = getPixelColor(device, 140, 101);
7588     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7589     color = getPixelColor(device, 135, 105);
7590     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7591     color = getPixelColor(device, 140, 105);
7592     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7593
7594     color = getPixelColor(device, 135, 376);
7595     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7596     color = getPixelColor(device, 140, 376);
7597     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7598     color = getPixelColor(device, 135, 379);
7599     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7600     color = getPixelColor(device, 140, 379);
7601     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7602
7603     color = getPixelColor(device, 500, 101);
7604     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7605     color = getPixelColor(device, 504, 101);
7606     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7607     color = getPixelColor(device, 500, 105);
7608     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7609     color = getPixelColor(device, 504, 105);
7610     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7611
7612     color = getPixelColor(device, 500, 376);
7613     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7614     color = getPixelColor(device, 504, 376);
7615     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7616     color = getPixelColor(device, 500, 380);
7617     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7618     color = getPixelColor(device, 504, 380);
7619     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7620
7621     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7622
7623     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7624     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7625     IDirect3DTexture9_Release(texture);
7626 }
7627
7628 static void vFace_register_test(IDirect3DDevice9 *device)
7629 {
7630     HRESULT hr;
7631     DWORD color;
7632     const DWORD shader_code[] = {
7633         0xffff0300,                                                             /* ps_3_0                     */
7634         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7635         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7636         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7637         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7638         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7639         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7640         0x0000ffff                                                              /* END                        */
7641     };
7642     const DWORD vshader_code[] = {
7643         0xfffe0300,                                                             /* vs_3_0               */
7644         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
7645         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
7646         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
7647         0x0000ffff                                                              /* end                  */
7648     };
7649     IDirect3DPixelShader9 *shader;
7650     IDirect3DVertexShader9 *vshader;
7651     IDirect3DTexture9 *texture;
7652     IDirect3DSurface9 *surface, *backbuffer;
7653     const float quad[] = {
7654         -1.0,   -1.0,   0.1,
7655          1.0,   -1.0,   0.1,
7656         -1.0,    0.0,   0.1,
7657
7658          1.0,   -1.0,   0.1,
7659          1.0,    0.0,   0.1,
7660         -1.0,    0.0,   0.1,
7661
7662         -1.0,    0.0,   0.1,
7663         -1.0,    1.0,   0.1,
7664          1.0,    0.0,   0.1,
7665
7666          1.0,    0.0,   0.1,
7667         -1.0,    1.0,   0.1,
7668          1.0,    1.0,   0.1,
7669     };
7670     const float blit[] = {
7671          0.0,   -1.0,   0.1,    0.0,    0.0,
7672          1.0,   -1.0,   0.1,    1.0,    0.0,
7673          0.0,    1.0,   0.1,    0.0,    1.0,
7674          1.0,    1.0,   0.1,    1.0,    1.0,
7675     };
7676
7677     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7678     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7679     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7680     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7681     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7682     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7683     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7684     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7685     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7686     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7687     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7688     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7689     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7690     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7691     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7692     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7693
7694     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7695     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7696
7697     hr = IDirect3DDevice9_BeginScene(device);
7698     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7699     if(SUCCEEDED(hr)) {
7700         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7701         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7702         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7703         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7704         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7705         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7706         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7707         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7708         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7709         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7710         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7711
7712         /* Blit the texture onto the back buffer to make it visible */
7713         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7714         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
7715         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7716         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7717         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7718         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7719         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7720         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7721         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7722         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7723         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7724         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7725
7726         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7727         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7728
7729         hr = IDirect3DDevice9_EndScene(device);
7730         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7731     }
7732
7733     color = getPixelColor(device, 160, 360);
7734     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7735     color = getPixelColor(device, 160, 120);
7736     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7737     color = getPixelColor(device, 480, 360);
7738     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7739     color = getPixelColor(device, 480, 120);
7740     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7741     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7742
7743     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7744     IDirect3DDevice9_SetTexture(device, 0, NULL);
7745     IDirect3DPixelShader9_Release(shader);
7746     IDirect3DVertexShader9_Release(vshader);
7747     IDirect3DSurface9_Release(surface);
7748     IDirect3DSurface9_Release(backbuffer);
7749     IDirect3DTexture9_Release(texture);
7750 }
7751
7752 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7753 {
7754     HRESULT hr;
7755     DWORD color;
7756     int i;
7757     D3DCAPS9 caps;
7758     BOOL L6V5U5_supported = FALSE;
7759     IDirect3DTexture9 *tex1, *tex2;
7760     D3DLOCKED_RECT locked_rect;
7761
7762     static const float quad[][7] = {
7763         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7764         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7765         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7766         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7767     };
7768
7769     static const D3DVERTEXELEMENT9 decl_elements[] = {
7770         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7771         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7772         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7773         D3DDECL_END()
7774     };
7775
7776     /* use asymmetric matrix to test loading */
7777     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7778     float scale, offset;
7779
7780     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7781     IDirect3DTexture9           *texture            = NULL;
7782
7783     memset(&caps, 0, sizeof(caps));
7784     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7785     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7786     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7787         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7788         return;
7789     } else {
7790         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7791          * They report that it is not supported, but after that bump mapping works properly. So just test
7792          * if the format is generally supported, and check the BUMPENVMAP flag
7793          */
7794         IDirect3D9 *d3d9;
7795
7796         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7797         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7798                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7799         L6V5U5_supported = SUCCEEDED(hr);
7800         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7801                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7802         IDirect3D9_Release(d3d9);
7803         if(FAILED(hr)) {
7804             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7805             return;
7806         }
7807     }
7808
7809     /* Generate the textures */
7810     generate_bumpmap_textures(device);
7811
7812     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7813     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7814     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7815     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7816     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7817     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7818     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7819     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7820
7821     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7822     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7823     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7824     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7825     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7826     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7827
7828     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7829     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7830     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7831     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7832     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7833     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7834
7835     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7836     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7837
7838     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7839     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7840
7841     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7842     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7843
7844
7845     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7846     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7847     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7848     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7849
7850     hr = IDirect3DDevice9_BeginScene(device);
7851     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7852
7853     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7854     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7855
7856     hr = IDirect3DDevice9_EndScene(device);
7857     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7858
7859     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7860      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7861      * But since testing the color match is not the purpose of the test don't be too picky
7862      */
7863     color = getPixelColor(device, 320-32, 240);
7864     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7865     color = getPixelColor(device, 320+32, 240);
7866     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7867     color = getPixelColor(device, 320, 240-32);
7868     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7869     color = getPixelColor(device, 320, 240+32);
7870     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7871     color = getPixelColor(device, 320, 240);
7872     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7873     color = getPixelColor(device, 320+32, 240+32);
7874     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7875     color = getPixelColor(device, 320-32, 240+32);
7876     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7877     color = getPixelColor(device, 320+32, 240-32);
7878     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7879     color = getPixelColor(device, 320-32, 240-32);
7880     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7881     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7882     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7883
7884     for(i = 0; i < 2; i++) {
7885         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7886         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7887         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7888         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7889         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7890         IDirect3DTexture9_Release(texture); /* To destroy it */
7891     }
7892
7893     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7894         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7895         goto cleanup;
7896     }
7897     if(L6V5U5_supported == FALSE) {
7898         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7899         goto cleanup;
7900     }
7901
7902     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7903     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7904     /* This test only tests the luminance part. The bumpmapping part was already tested above and
7905      * would only make this test more complicated
7906      */
7907     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7908     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7909     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7910     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7911
7912     memset(&locked_rect, 0, sizeof(locked_rect));
7913     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7914     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7915     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7916     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7917     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7918
7919     memset(&locked_rect, 0, sizeof(locked_rect));
7920     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7921     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7922     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7923     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7924     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7925
7926     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7927     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7928     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7929     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7930
7931     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7932     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7933     scale = 2.0;
7934     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7935     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7936     offset = 0.1;
7937     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7938     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7939
7940     hr = IDirect3DDevice9_BeginScene(device);
7941     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7942     if(SUCCEEDED(hr)) {
7943         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7944         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7945         hr = IDirect3DDevice9_EndScene(device);
7946         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7947     }
7948
7949     color = getPixelColor(device, 320, 240);
7950     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
7951      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
7952      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7953      */
7954     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7955     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7956     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7957
7958     /* Check a result scale factor > 1.0 */
7959     scale = 10;
7960     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7961     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7962     offset = 10;
7963     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7964     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7965
7966     hr = IDirect3DDevice9_BeginScene(device);
7967     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7968     if(SUCCEEDED(hr)) {
7969         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7970         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7971         hr = IDirect3DDevice9_EndScene(device);
7972         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7973     }
7974     color = getPixelColor(device, 320, 240);
7975     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7976     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7977     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7978
7979     /* Check clamping in the scale factor calculation */
7980     scale = 1000;
7981     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7982     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7983     offset = -1;
7984     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7985     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7986
7987     hr = IDirect3DDevice9_BeginScene(device);
7988     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7989     if(SUCCEEDED(hr)) {
7990         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7991         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7992         hr = IDirect3DDevice9_EndScene(device);
7993         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7994     }
7995     color = getPixelColor(device, 320, 240);
7996     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7997     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7998     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7999
8000     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8001     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8002     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8003     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8004
8005     IDirect3DTexture9_Release(tex1);
8006     IDirect3DTexture9_Release(tex2);
8007
8008 cleanup:
8009     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8010     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8011     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8012     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8013
8014     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8015     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8016     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8017 }
8018
8019 static void stencil_cull_test(IDirect3DDevice9 *device) {
8020     HRESULT hr;
8021     IDirect3DSurface9 *depthstencil = NULL;
8022     D3DSURFACE_DESC desc;
8023     float quad1[] = {
8024         -1.0,   -1.0,   0.1,
8025          0.0,   -1.0,   0.1,
8026         -1.0,    0.0,   0.1,
8027          0.0,    0.0,   0.1,
8028     };
8029     float quad2[] = {
8030          0.0,   -1.0,   0.1,
8031          1.0,   -1.0,   0.1,
8032          0.0,    0.0,   0.1,
8033          1.0,    0.0,   0.1,
8034     };
8035     float quad3[] = {
8036         0.0,    0.0,   0.1,
8037         1.0,    0.0,   0.1,
8038         0.0,    1.0,   0.1,
8039         1.0,    1.0,   0.1,
8040     };
8041     float quad4[] = {
8042         -1.0,    0.0,   0.1,
8043          0.0,    0.0,   0.1,
8044         -1.0,    1.0,   0.1,
8045          0.0,    1.0,   0.1,
8046     };
8047     struct vertex painter[] = {
8048        {-1.0,   -1.0,   0.0,    0x00000000},
8049        { 1.0,   -1.0,   0.0,    0x00000000},
8050        {-1.0,    1.0,   0.0,    0x00000000},
8051        { 1.0,    1.0,   0.0,    0x00000000},
8052     };
8053     WORD indices_cw[]  = {0, 1, 3};
8054     WORD indices_ccw[] = {0, 2, 3};
8055     unsigned int i;
8056     DWORD color;
8057
8058     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8059     if(depthstencil == NULL) {
8060         skip("No depth stencil buffer\n");
8061         return;
8062     }
8063     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8064     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8065     IDirect3DSurface9_Release(depthstencil);
8066     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8067         skip("No 4 or 8 bit stencil surface\n");
8068         return;
8069     }
8070
8071     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8072     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8073     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8074
8075     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8076     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8077     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8078     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8079     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8080     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8081     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8082     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8083
8084     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8085     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8086     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8087     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8088     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8089     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8090
8091     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8092     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8093     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8094     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8095
8096     /* First pass: Fill the stencil buffer with some values... */
8097     hr = IDirect3DDevice9_BeginScene(device);
8098     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8099     if(SUCCEEDED(hr))
8100     {
8101         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8102         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8103         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8104                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8105         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8106         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8107                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8108         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8109
8110         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8111         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8112         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8113         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8114         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8115                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8116         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8117         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8118                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8119         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8120
8121         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8122         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8123         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8124                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8125         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8126         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8127                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8128         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8129
8130         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8131         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8132         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8133                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8134         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8135         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8136                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8137         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8138
8139         hr = IDirect3DDevice9_EndScene(device);
8140         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8141     }
8142
8143     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8144     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8145     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8146     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8147     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8148     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8149     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8150     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8151     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8152     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8153     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8154     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8155     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8156
8157     /* 2nd pass: Make the stencil values visible */
8158     hr = IDirect3DDevice9_BeginScene(device);
8159     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8160     if(SUCCEEDED(hr))
8161     {
8162         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8163         for(i = 0; i < 16; i++) {
8164             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8165             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8166
8167             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8168             painter[1].diffuse = (i * 16);
8169             painter[2].diffuse = (i * 16);
8170             painter[3].diffuse = (i * 16);
8171             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8172             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8173         }
8174         hr = IDirect3DDevice9_EndScene(device);
8175         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8176     }
8177
8178     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8179     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8180
8181     color = getPixelColor(device, 160, 420);
8182     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8183     color = getPixelColor(device, 160, 300);
8184     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8185
8186     color = getPixelColor(device, 480, 420);
8187     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8188     color = getPixelColor(device, 480, 300);
8189     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8190
8191     color = getPixelColor(device, 160, 180);
8192     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8193     color = getPixelColor(device, 160, 60);
8194     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8195
8196     color = getPixelColor(device, 480, 180);
8197     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8198     color = getPixelColor(device, 480, 60);
8199     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8200
8201     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8202     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8203 }
8204
8205 static void vpos_register_test(IDirect3DDevice9 *device)
8206 {
8207     HRESULT hr;
8208     DWORD color;
8209     const DWORD shader_code[] = {
8210     0xffff0300,                                                             /* ps_3_0                     */
8211     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8212     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8213     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8214     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8215     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8216     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8217     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8218     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8219     0x0000ffff                                                              /* end                        */
8220     };
8221     const DWORD shader_frac_code[] = {
8222     0xffff0300,                                                             /* ps_3_0                     */
8223     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8224     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8225     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8226     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8227     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8228     0x0000ffff                                                              /* end                        */
8229     };
8230     const DWORD vshader_code[] = {
8231         0xfffe0300,                                                             /* vs_3_0               */
8232         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8233         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8234         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8235         0x0000ffff                                                              /* end                  */
8236     };
8237     IDirect3DVertexShader9 *vshader;
8238     IDirect3DPixelShader9 *shader, *shader_frac;
8239     IDirect3DSurface9 *surface = NULL, *backbuffer;
8240     const float quad[] = {
8241         -1.0,   -1.0,   0.1,    0.0,    0.0,
8242          1.0,   -1.0,   0.1,    1.0,    0.0,
8243         -1.0,    1.0,   0.1,    0.0,    1.0,
8244          1.0,    1.0,   0.1,    1.0,    1.0,
8245     };
8246     D3DLOCKED_RECT lr;
8247     float constant[4] = {1.0, 0.0, 320, 240};
8248     DWORD *pos;
8249
8250     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8251     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8252     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8253     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8254     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8255     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8256     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8257     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8258     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8259     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8260     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8261     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8262     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8263     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8264     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8265     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8266
8267     hr = IDirect3DDevice9_BeginScene(device);
8268     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8269     if(SUCCEEDED(hr)) {
8270         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8271         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8272         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8273         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8274         hr = IDirect3DDevice9_EndScene(device);
8275         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8276     }
8277
8278     /* This has to be pixel exact */
8279     color = getPixelColor(device, 319, 239);
8280     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8281     color = getPixelColor(device, 320, 239);
8282     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8283     color = getPixelColor(device, 319, 240);
8284     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8285     color = getPixelColor(device, 320, 240);
8286     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8287     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8288
8289     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8290                                              &surface, NULL);
8291     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8292     hr = IDirect3DDevice9_BeginScene(device);
8293     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8294     if(SUCCEEDED(hr)) {
8295         constant[2] = 16; constant[3] = 16;
8296         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8297         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8298         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8299         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8300         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8301         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8302         hr = IDirect3DDevice9_EndScene(device);
8303         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8304     }
8305     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8306     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8307
8308     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8309     color = *pos & 0x00ffffff;
8310     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8311     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8312     color = *pos & 0x00ffffff;
8313     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8314     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8315     color = *pos & 0x00ffffff;
8316     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8317     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8318     color = *pos & 0x00ffffff;
8319     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8320
8321     hr = IDirect3DSurface9_UnlockRect(surface);
8322     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8323
8324     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8325      * have full control over the multisampling setting inside this test
8326      */
8327     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8328     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8329     hr = IDirect3DDevice9_BeginScene(device);
8330     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8331     if(SUCCEEDED(hr)) {
8332         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8333         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8334         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8335         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8336         hr = IDirect3DDevice9_EndScene(device);
8337         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8338     }
8339     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8340     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8341
8342     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8343     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8344
8345     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8346     color = *pos & 0x00ffffff;
8347     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8348
8349     hr = IDirect3DSurface9_UnlockRect(surface);
8350     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8351
8352     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8353     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8354     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8355     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8356     IDirect3DPixelShader9_Release(shader);
8357     IDirect3DPixelShader9_Release(shader_frac);
8358     IDirect3DVertexShader9_Release(vshader);
8359     if(surface) IDirect3DSurface9_Release(surface);
8360     IDirect3DSurface9_Release(backbuffer);
8361 }
8362
8363 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8364 {
8365     D3DCOLOR color;
8366
8367     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8368     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8369     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8370     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8371     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8372
8373     ++r;
8374     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8375     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8376     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8377     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8378     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8379
8380     return TRUE;
8381 }
8382
8383 static void pointsize_test(IDirect3DDevice9 *device)
8384 {
8385     HRESULT hr;
8386     D3DCAPS9 caps;
8387     D3DMATRIX matrix;
8388     D3DMATRIX identity;
8389     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8390     DWORD color;
8391     IDirect3DSurface9 *rt, *backbuffer;
8392     IDirect3DTexture9 *tex1, *tex2;
8393     RECT rect = {0, 0, 128, 128};
8394     D3DLOCKED_RECT lr;
8395     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8396                                 0x00000000, 0x00000000};
8397     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8398                                 0x00000000, 0x0000ff00};
8399
8400     const float vertices[] = {
8401         64,     64,     0.1,
8402         128,    64,     0.1,
8403         192,    64,     0.1,
8404         256,    64,     0.1,
8405         320,    64,     0.1,
8406         384,    64,     0.1,
8407         448,    64,     0.1,
8408         512,    64,     0.1,
8409     };
8410
8411     /* 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 */
8412     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;
8413     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;
8414     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;
8415     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;
8416
8417     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;
8418     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;
8419     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;
8420     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;
8421
8422     memset(&caps, 0, sizeof(caps));
8423     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8424     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8425     if(caps.MaxPointSize < 32.0) {
8426         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8427         return;
8428     }
8429
8430     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8431     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8432     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8433     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8434     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8435     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8436     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8437     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8438
8439     hr = IDirect3DDevice9_BeginScene(device);
8440     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8441     if (SUCCEEDED(hr))
8442     {
8443         ptsize = 15.0;
8444         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8445         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8446         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8447         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8448
8449         ptsize = 31.0;
8450         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8451         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8452         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8453         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8454
8455         ptsize = 30.75;
8456         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8457         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8458         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8459         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8460
8461         if (caps.MaxPointSize >= 63.0)
8462         {
8463             ptsize = 63.0;
8464             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8465             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8466             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8467             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8468
8469             ptsize = 62.75;
8470             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8471             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8472             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8473             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8474         }
8475
8476         ptsize = 1.0;
8477         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8478         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8479         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8480         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8481
8482         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8483         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8484         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8485         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8486
8487         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8488         ptsize = 15.0;
8489         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8490         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8491         ptsize = 1.0;
8492         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8493         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8494         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8495         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8496
8497         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8498         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8499
8500         /* pointsize < pointsize_min < pointsize_max?
8501          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8502         ptsize = 1.0;
8503         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8504         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8505         ptsize = 15.0;
8506         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8507         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8508         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8509         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8510
8511         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8512         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8513
8514         hr = IDirect3DDevice9_EndScene(device);
8515         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8516     }
8517
8518     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8519     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8520     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8521
8522     if (caps.MaxPointSize >= 63.0)
8523     {
8524         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8525         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8526     }
8527
8528     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8529     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8530     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8531     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8532     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8533
8534     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8535
8536     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8537      * generates texture coordinates for the point(result: Yes, it does)
8538      *
8539      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8540      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8541      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8542      */
8543     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8544     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8545
8546     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8547     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8548     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8549     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8550     memset(&lr, 0, sizeof(lr));
8551     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8552     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8553     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8554     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8555     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8556     memset(&lr, 0, sizeof(lr));
8557     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8558     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8559     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8560     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8561     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8562     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8563     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8564     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8565     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8566     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8567     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8568     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8569     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8570     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8571     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8572     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8573     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8574     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8575     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8576
8577     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8578     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8579     ptsize = 32.0;
8580     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8581     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8582
8583     hr = IDirect3DDevice9_BeginScene(device);
8584     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8585     if(SUCCEEDED(hr))
8586     {
8587         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8588         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8589         hr = IDirect3DDevice9_EndScene(device);
8590         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8591     }
8592
8593     color = getPixelColor(device, 64-4, 64-4);
8594     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8595     color = getPixelColor(device, 64-4, 64+4);
8596     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8597     color = getPixelColor(device, 64+4, 64+4);
8598     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8599     color = getPixelColor(device, 64+4, 64-4);
8600     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8601     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8602
8603     U(matrix).m[0][0] =  1.0f / 64.0f;
8604     U(matrix).m[1][1] = -1.0f / 64.0f;
8605     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8606     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8607
8608     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8609     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8610
8611     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8612             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8613     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8614
8615     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8616     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8617     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
8618     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
8619
8620     hr = IDirect3DDevice9_BeginScene(device);
8621     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8622     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8623     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8624     hr = IDirect3DDevice9_EndScene(device);
8625     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8626
8627     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
8628     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
8629     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8630     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8631     IDirect3DSurface9_Release(backbuffer);
8632     IDirect3DSurface9_Release(rt);
8633
8634     color = getPixelColor(device, 64-4, 64-4);
8635     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
8636             "Expected color 0x00ff0000, got 0x%08x.\n", color);
8637     color = getPixelColor(device, 64+4, 64-4);
8638     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
8639             "Expected color 0x00ffff00, got 0x%08x.\n", color);
8640     color = getPixelColor(device, 64-4, 64+4);
8641     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
8642             "Expected color 0x00000000, got 0x%08x.\n", color);
8643     color = getPixelColor(device, 64+4, 64+4);
8644     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8645             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8646
8647     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8648     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8649
8650     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8651     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8652     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8653     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8654     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8655     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8656     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8657     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8658     IDirect3DTexture9_Release(tex1);
8659     IDirect3DTexture9_Release(tex2);
8660
8661     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8662     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8663     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8664     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8665     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8666     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8667 }
8668
8669 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8670 {
8671     static const DWORD vshader_code[] =
8672     {
8673         0xfffe0300,                                                             /* vs_3_0                     */
8674         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0            */
8675         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0            */
8676         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                 */
8677         0x0000ffff                                                              /* end                        */
8678     };
8679     static const DWORD pshader_code[] =
8680     {
8681         0xffff0300,                                                             /* ps_3_0                     */
8682         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8683         0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
8684         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
8685         0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1                */
8686         0x0000ffff                                                              /* end                        */
8687     };
8688
8689     HRESULT hr;
8690     IDirect3DVertexShader9 *vs;
8691     IDirect3DPixelShader9 *ps;
8692     IDirect3DTexture9 *tex1, *tex2;
8693     IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
8694     D3DCAPS9 caps;
8695     DWORD color;
8696     float quad[] = {
8697        -1.0,   -1.0,    0.1,
8698         1.0,   -1.0,    0.1,
8699        -1.0,    1.0,    0.1,
8700         1.0,    1.0,    0.1,
8701     };
8702     float texquad[] = {
8703        -1.0,   -1.0,    0.1,    0.0,    0.0,
8704         0.0,   -1.0,    0.1,    1.0,    0.0,
8705        -1.0,    1.0,    0.1,    0.0,    1.0,
8706         0.0,    1.0,    0.1,    1.0,    1.0,
8707
8708         0.0,   -1.0,    0.1,    0.0,    0.0,
8709         1.0,   -1.0,    0.1,    1.0,    0.0,
8710         0.0,    1.0,    0.1,    0.0,    1.0,
8711         1.0,    1.0,    0.1,    1.0,    1.0,
8712     };
8713
8714     memset(&caps, 0, sizeof(caps));
8715     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8716     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8717     if(caps.NumSimultaneousRTs < 2) {
8718         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8719         return;
8720     }
8721
8722     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8723     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8724
8725     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
8726             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
8727     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
8728
8729     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8730             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8731     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8732     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8733             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8734     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8735     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
8736     ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
8737     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &ps);
8738     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8739
8740     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8741     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8742     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8743     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8744     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8745     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8746
8747     hr = IDirect3DDevice9_SetVertexShader(device, vs);
8748     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8749     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8750     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8751     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8752     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8753     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8754     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8755     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8756     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8757
8758     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8759     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8760     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8761     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8762     color = getPixelColorFromSurface(readback, 8, 8);
8763     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8764             "Expected color 0x000000ff, got 0x%08x.\n", color);
8765     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8766     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8767     color = getPixelColorFromSurface(readback, 8, 8);
8768     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8769             "Expected color 0x000000ff, got 0x%08x.\n", color);
8770
8771     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8772     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8773     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8774     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8775     color = getPixelColorFromSurface(readback, 8, 8);
8776     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8777             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8778     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8779     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8780     color = getPixelColorFromSurface(readback, 8, 8);
8781     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8782             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8783
8784     hr = IDirect3DDevice9_BeginScene(device);
8785     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8786     if(SUCCEEDED(hr)) {
8787         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8788         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8789
8790         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8791         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8792         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8793         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8794         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8795         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8796         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8797         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8798         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8799         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8800
8801         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8802         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8803         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8804         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8805
8806         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8807         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8808         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8809         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8810
8811         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8812         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8813
8814         hr = IDirect3DDevice9_EndScene(device);
8815         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8816     }
8817
8818     color = getPixelColor(device, 160, 240);
8819     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8820     color = getPixelColor(device, 480, 240);
8821     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8822     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8823
8824     IDirect3DPixelShader9_Release(ps);
8825     IDirect3DVertexShader9_Release(vs);
8826     IDirect3DTexture9_Release(tex1);
8827     IDirect3DTexture9_Release(tex2);
8828     IDirect3DSurface9_Release(surf1);
8829     IDirect3DSurface9_Release(surf2);
8830     IDirect3DSurface9_Release(backbuf);
8831     IDirect3DSurface9_Release(readback);
8832 }
8833
8834 struct formats {
8835     const char *fmtName;
8836     D3DFORMAT textureFormat;
8837     DWORD resultColorBlending;
8838     DWORD resultColorNoBlending;
8839 };
8840
8841 static const struct formats test_formats[] = {
8842   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8843   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8844   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8845   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8846   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8847   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8848   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8849   { NULL, 0 }
8850 };
8851
8852 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8853 {
8854     HRESULT hr;
8855     IDirect3DTexture9 *offscreenTexture = NULL;
8856     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8857     IDirect3D9 *d3d = NULL;
8858     DWORD color;
8859     DWORD r0, g0, b0, r1, g1, b1;
8860     int fmt_index;
8861
8862     static const float quad[][5] = {
8863         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8864         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8865         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8866         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8867     };
8868
8869     /* Quad with R=0x10, G=0x20 */
8870     static const struct vertex quad1[] = {
8871         {-1.0f, -1.0f, 0.1f, 0x80102000},
8872         {-1.0f,  1.0f, 0.1f, 0x80102000},
8873         { 1.0f, -1.0f, 0.1f, 0x80102000},
8874         { 1.0f,  1.0f, 0.1f, 0x80102000},
8875     };
8876
8877     /* Quad with R=0x20, G=0x10 */
8878     static const struct vertex quad2[] = {
8879         {-1.0f, -1.0f, 0.1f, 0x80201000},
8880         {-1.0f,  1.0f, 0.1f, 0x80201000},
8881         { 1.0f, -1.0f, 0.1f, 0x80201000},
8882         { 1.0f,  1.0f, 0.1f, 0x80201000},
8883     };
8884
8885     IDirect3DDevice9_GetDirect3D(device, &d3d);
8886
8887     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8888     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8889     if(!backbuffer) {
8890         goto out;
8891     }
8892
8893     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8894     {
8895         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8896
8897         if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
8898                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
8899         {
8900             skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
8901             continue;
8902         }
8903
8904         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8905         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8906
8907         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8908         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8909         if(!offscreenTexture) {
8910             continue;
8911         }
8912
8913         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8914         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8915         if(!offscreen) {
8916             continue;
8917         }
8918
8919         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8920         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8921
8922         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8923         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8924         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8925         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8926         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8927         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8928         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8929         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8930         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8931         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8932
8933         /* Below we will draw two quads with different colors and try to blend them together.
8934          * The result color is compared with the expected outcome.
8935          */
8936         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8937             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8938             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8939             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8940             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8941
8942             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8943             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8944
8945             /* Draw a quad using color 0x0010200 */
8946             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8947             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8948             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8949             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8950             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8951             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8952
8953             /* Draw a quad using color 0x0020100 */
8954             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8955             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8956             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8957             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8958             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8959             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8960
8961             /* We don't want to blend the result on the backbuffer */
8962             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8963             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8964
8965             /* Prepare rendering the 'blended' texture quad to the backbuffer */
8966             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8967             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8968             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8969             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8970
8971             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8972             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8973
8974             /* This time with the texture */
8975             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8976             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8977
8978             IDirect3DDevice9_EndScene(device);
8979         }
8980
8981         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8982             /* Compare the color of the center quad with our expectation */
8983             color = getPixelColor(device, 320, 240);
8984             r0 = (color & 0x00ff0000) >> 16;
8985             g0 = (color & 0x0000ff00) >>  8;
8986             b0 = (color & 0x000000ff) >>  0;
8987
8988             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8989             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
8990             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
8991
8992             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8993                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8994                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8995                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8996         } else {
8997             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
8998              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8999              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9000             color = getPixelColor(device, 320, 240);
9001             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);
9002         }
9003         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9004
9005         IDirect3DDevice9_SetTexture(device, 0, NULL);
9006         if(offscreenTexture) {
9007             IDirect3DTexture9_Release(offscreenTexture);
9008         }
9009         if(offscreen) {
9010             IDirect3DSurface9_Release(offscreen);
9011         }
9012     }
9013
9014 out:
9015     /* restore things */
9016     if(backbuffer) {
9017         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9018         IDirect3DSurface9_Release(backbuffer);
9019     }
9020 }
9021
9022 static void tssargtemp_test(IDirect3DDevice9 *device)
9023 {
9024     HRESULT hr;
9025     DWORD color;
9026     static const struct vertex quad[] = {
9027         {-1.0,     -1.0,    0.1,    0x00ff0000},
9028         { 1.0,     -1.0,    0.1,    0x00ff0000},
9029         {-1.0,      1.0,    0.1,    0x00ff0000},
9030         { 1.0,      1.0,    0.1,    0x00ff0000}
9031     };
9032     D3DCAPS9 caps;
9033
9034     memset(&caps, 0, sizeof(caps));
9035     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9036     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9037     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9038         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9039         return;
9040     }
9041
9042     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9043     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9044
9045     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9046     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9047     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9048     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9049
9050     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9051     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9052     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9053     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9054     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9055     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9056
9057     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9058     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9059     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9060     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9061     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9062     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9063
9064     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9065     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9066
9067     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9068     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9069     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9070     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9071
9072     hr = IDirect3DDevice9_BeginScene(device);
9073     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9074     if(SUCCEEDED(hr)) {
9075         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9076         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9077         hr = IDirect3DDevice9_EndScene(device);
9078         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9079     }
9080     color = getPixelColor(device, 320, 240);
9081     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9082     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9083
9084     /* Set stage 1 back to default */
9085     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9086     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9087     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9088     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9089     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9090     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9091     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9092     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9093     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9094     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9095 }
9096
9097 struct testdata
9098 {
9099     DWORD idxVertex; /* number of instances in the first stream */
9100     DWORD idxColor; /* number of instances in the second stream */
9101     DWORD idxInstance; /* should be 1 ?? */
9102     DWORD color1; /* color 1 instance */
9103     DWORD color2; /* color 2 instance */
9104     DWORD color3; /* color 3 instance */
9105     DWORD color4; /* color 4 instance */
9106     WORD strVertex; /* specify which stream to use 0-2*/
9107     WORD strColor;
9108     WORD strInstance;
9109 };
9110
9111 static const struct testdata testcases[]=
9112 {
9113     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9114     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9115     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9116     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9117     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
9118     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9119     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9120     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9121     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
9122     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
9123     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9124     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9125     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9126     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9127     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9128 /*
9129     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9130     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9131 */
9132 };
9133
9134 /* Drawing Indexed Geometry with instances*/
9135 static void stream_test(IDirect3DDevice9 *device)
9136 {
9137     IDirect3DVertexBuffer9 *vb = NULL;
9138     IDirect3DVertexBuffer9 *vb2 = NULL;
9139     IDirect3DVertexBuffer9 *vb3 = NULL;
9140     IDirect3DIndexBuffer9 *ib = NULL;
9141     IDirect3DVertexDeclaration9 *pDecl = NULL;
9142     IDirect3DVertexShader9 *shader = NULL;
9143     HRESULT hr;
9144     BYTE *data;
9145     DWORD color;
9146     DWORD ind;
9147     unsigned i;
9148
9149     const DWORD shader_code[] =
9150     {
9151         0xfffe0101,                                     /* vs_1_1 */
9152         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9153         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9154         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9155         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9156         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9157         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9158         0x0000ffff
9159     };
9160
9161     const float quad[][3] =
9162     {
9163         {-0.5f, -0.5f,  1.1f}, /*0 */
9164         {-0.5f,  0.5f,  1.1f}, /*1 */
9165         { 0.5f, -0.5f,  1.1f}, /*2 */
9166         { 0.5f,  0.5f,  1.1f}, /*3 */
9167     };
9168
9169     const float vertcolor[][4] =
9170     {
9171         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9172         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9173         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9174         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9175     };
9176
9177     /* 4 position for 4 instances */
9178     const float instancepos[][3] =
9179     {
9180         {-0.6f,-0.6f, 0.0f},
9181         { 0.6f,-0.6f, 0.0f},
9182         { 0.6f, 0.6f, 0.0f},
9183         {-0.6f, 0.6f, 0.0f},
9184     };
9185
9186     short indices[] = {0, 1, 2, 1, 2, 3};
9187
9188     D3DVERTEXELEMENT9 decl[] =
9189     {
9190         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9191         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9192         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9193         D3DDECL_END()
9194     };
9195
9196     /* set the default value because it isn't done in wine? */
9197     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9198     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9199
9200     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9201     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9202     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9203
9204     /* check wrong cases */
9205     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9206     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9207     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9208     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9209     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9210     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9211     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9212     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9213     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9214     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9215     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9216     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9217     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9218     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9219     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9220     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9221     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9222     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9223     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9224     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9225
9226     /* set the default value back */
9227     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9228     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9229
9230     /* create all VertexBuffers*/
9231     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9232     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9233     if(!vb) {
9234         skip("Failed to create a vertex buffer\n");
9235         return;
9236     }
9237     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9238     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9239     if(!vb2) {
9240         skip("Failed to create a vertex buffer\n");
9241         goto out;
9242     }
9243     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9244     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9245     if(!vb3) {
9246         skip("Failed to create a vertex buffer\n");
9247         goto out;
9248     }
9249
9250     /* create IndexBuffer*/
9251     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9252     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9253     if(!ib) {
9254         skip("Failed to create a index buffer\n");
9255         goto out;
9256     }
9257
9258     /* copy all Buffers (Vertex + Index)*/
9259     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9260     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9261     memcpy(data, quad, sizeof(quad));
9262     hr = IDirect3DVertexBuffer9_Unlock(vb);
9263     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9264     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9265     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9266     memcpy(data, vertcolor, sizeof(vertcolor));
9267     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9268     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9269     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9270     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9271     memcpy(data, instancepos, sizeof(instancepos));
9272     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9273     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9274     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9275     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9276     memcpy(data, indices, sizeof(indices));
9277     hr = IDirect3DIndexBuffer9_Unlock(ib);
9278     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9279
9280     /* create VertexShader */
9281     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9282     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9283     if(!shader) {
9284         skip("Failed to create a vetex shader\n");
9285         goto out;
9286     }
9287
9288     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9289     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9290
9291     hr = IDirect3DDevice9_SetIndices(device, ib);
9292     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9293
9294     /* run all tests */
9295     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9296     {
9297         struct testdata act = testcases[i];
9298         decl[0].Stream = act.strVertex;
9299         decl[1].Stream = act.strColor;
9300         decl[2].Stream = act.strInstance;
9301         /* create VertexDeclarations */
9302         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9303         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9304
9305         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9306         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9307
9308         hr = IDirect3DDevice9_BeginScene(device);
9309         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9310         if(SUCCEEDED(hr))
9311         {
9312             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9313             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9314
9315             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9316             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9317             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9318             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9319
9320             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9321             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9322             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9323             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9324
9325             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9326             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9327             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9328             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9329
9330             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9331             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9332             hr = IDirect3DDevice9_EndScene(device);
9333             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9334
9335             /* set all StreamSource && StreamSourceFreq back to default */
9336             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9337             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9338             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9339             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9340             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9341             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9342             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9343             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9344             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9345             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9346             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9347             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9348         }
9349
9350         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9351         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9352
9353         color = getPixelColor(device, 160, 360);
9354         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9355         color = getPixelColor(device, 480, 360);
9356         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9357         color = getPixelColor(device, 480, 120);
9358         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9359         color = getPixelColor(device, 160, 120);
9360         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9361
9362         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9363         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9364     }
9365
9366     hr = IDirect3DDevice9_SetIndices(device, NULL);
9367     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9368
9369 out:
9370     if(vb) IDirect3DVertexBuffer9_Release(vb);
9371     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9372     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9373     if(ib)IDirect3DIndexBuffer9_Release(ib);
9374     if(shader)IDirect3DVertexShader9_Release(shader);
9375 }
9376
9377 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9378     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9379     IDirect3DTexture9 *dsttex = NULL;
9380     HRESULT hr;
9381     DWORD color;
9382     D3DRECT r1 = {0,  0,  50,  50 };
9383     D3DRECT r2 = {50, 0,  100, 50 };
9384     D3DRECT r3 = {50, 50, 100, 100};
9385     D3DRECT r4 = {0,  50,  50, 100};
9386     const float quad[] = {
9387         -1.0,   -1.0,   0.1,    0.0,    0.0,
9388          1.0,   -1.0,   0.1,    1.0,    0.0,
9389         -1.0,    1.0,   0.1,    0.0,    1.0,
9390          1.0,    1.0,   0.1,    1.0,    1.0,
9391     };
9392
9393     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9394     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9395
9396     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9397     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9398     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9399     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9400
9401     if(!src || !dsttex) {
9402         skip("One or more test resources could not be created\n");
9403         goto cleanup;
9404     }
9405
9406     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9407     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9408
9409     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9410     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9411
9412     /* Clear the StretchRect destination for debugging */
9413     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9414     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9415     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9416     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9417
9418     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9419     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9420
9421     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9422     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9423     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9424     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9425     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9426     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9427     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9428     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9429
9430     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9431      * the target -> texture GL blit path
9432      */
9433     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9434     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9435     IDirect3DSurface9_Release(dst);
9436
9437     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9438     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9439
9440     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9441     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9442     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9443     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9444     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9445     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9446     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9447     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9448
9449     hr = IDirect3DDevice9_BeginScene(device);
9450     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9451     if(SUCCEEDED(hr)) {
9452         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9453         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9454         hr = IDirect3DDevice9_EndScene(device);
9455         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9456     }
9457
9458     color = getPixelColor(device, 160, 360);
9459     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9460     color = getPixelColor(device, 480, 360);
9461     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9462     color = getPixelColor(device, 480, 120);
9463     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9464     color = getPixelColor(device, 160, 120);
9465     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9466     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9467     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9468
9469     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9470     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9471     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9472     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9473
9474 cleanup:
9475     if(src) IDirect3DSurface9_Release(src);
9476     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9477     if(dsttex) IDirect3DTexture9_Release(dsttex);
9478 }
9479
9480 static void texop_test(IDirect3DDevice9 *device)
9481 {
9482     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9483     IDirect3DTexture9 *texture = NULL;
9484     D3DLOCKED_RECT locked_rect;
9485     D3DCOLOR color;
9486     D3DCAPS9 caps;
9487     HRESULT hr;
9488     unsigned i;
9489
9490     static const struct {
9491         float x, y, z;
9492         float s, t;
9493         D3DCOLOR diffuse;
9494     } quad[] = {
9495         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9496         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9497         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9498         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9499     };
9500
9501     static const D3DVERTEXELEMENT9 decl_elements[] = {
9502         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9503         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9504         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9505         D3DDECL_END()
9506     };
9507
9508     static const struct {
9509         D3DTEXTUREOP op;
9510         const char *name;
9511         DWORD caps_flag;
9512         D3DCOLOR result;
9513     } test_data[] = {
9514         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9515         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9516         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9517         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9518         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9519         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9520         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9521         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9522         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9523         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9524         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9525         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9526         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9527         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9528         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9529         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9530         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9531         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9532         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9533         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9534         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9535         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9536         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9537     };
9538
9539     memset(&caps, 0, sizeof(caps));
9540     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9541     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9542
9543     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9544     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9545     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9546     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9547
9548     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9549     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9550     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9551     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9552     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9553     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9554     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9555     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9556     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9557
9558     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9559     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9560     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9561     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9562     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9563     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9564
9565     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9566     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9567
9568     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9569     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9570     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9571     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9572     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9573     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9574
9575     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9576     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9577
9578     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9579     {
9580         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9581         {
9582             skip("tex operation %s not supported\n", test_data[i].name);
9583             continue;
9584         }
9585
9586         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9587         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9588
9589         hr = IDirect3DDevice9_BeginScene(device);
9590         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9591
9592         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9593         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9594
9595         hr = IDirect3DDevice9_EndScene(device);
9596         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9597
9598         color = getPixelColor(device, 320, 240);
9599         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9600                 test_data[i].name, color, test_data[i].result);
9601
9602         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9603         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9604     }
9605
9606     if (texture) IDirect3DTexture9_Release(texture);
9607     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9608 }
9609
9610 static void yuv_color_test(IDirect3DDevice9 *device) {
9611     HRESULT hr;
9612     IDirect3DSurface9 *surface = NULL, *target = NULL;
9613     unsigned int fmt, i;
9614     D3DFORMAT format;
9615     const char *fmt_string;
9616     D3DLOCKED_RECT lr;
9617     IDirect3D9 *d3d;
9618     HRESULT color;
9619     DWORD ref_color_left, ref_color_right;
9620
9621     struct {
9622         DWORD in;           /* The input color */
9623         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9624         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9625         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9626         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9627     } test_data[] = {
9628     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9629      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9630      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9631      * that
9632      */
9633       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9634       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9635       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9636       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9637       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9638       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9639       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9640       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9641       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9642       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9643       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9644       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9645       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9646       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9647
9648       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9649       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9650       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9651       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9652     };
9653
9654     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9655     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9656     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9657     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9658
9659     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9660     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9661
9662     for(fmt = 0; fmt < 2; fmt++) {
9663         if(fmt == 0) {
9664             format = D3DFMT_UYVY;
9665             fmt_string = "D3DFMT_UYVY";
9666         } else {
9667             format = D3DFMT_YUY2;
9668             fmt_string = "D3DFMT_YUY2";
9669         }
9670
9671         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9672                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9673                        */
9674         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9675                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9676             skip("%s is not supported\n", fmt_string);
9677             continue;
9678         }
9679
9680         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9681         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9682         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9683
9684         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9685             if(fmt == 0) {
9686                 ref_color_left = test_data[i].uyvy_left;
9687                 ref_color_right = test_data[i].uyvy_right;
9688             } else {
9689                 ref_color_left = test_data[i].yuy2_left;
9690                 ref_color_right = test_data[i].yuy2_right;
9691             }
9692
9693             memset(&lr, 0, sizeof(lr));
9694             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9695             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9696             *((DWORD *) lr.pBits) = test_data[i].in;
9697             hr = IDirect3DSurface9_UnlockRect(surface);
9698             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9699
9700             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9701             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9702             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9703             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9704
9705             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9706              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9707              * want to add tests for the filtered pixels as well.
9708              *
9709              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9710              * differently, so we need a max diff of 16
9711              */
9712             color = getPixelColor(device, 40, 240);
9713             ok(color_match(color, ref_color_left, 18),
9714                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9715                test_data[i].in, color, ref_color_left, fmt_string);
9716             color = getPixelColor(device, 600, 240);
9717             ok(color_match(color, ref_color_right, 18),
9718                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9719                test_data[i].in, color, ref_color_right, fmt_string);
9720             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9721             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9722         }
9723         IDirect3DSurface9_Release(surface);
9724     }
9725     IDirect3DSurface9_Release(target);
9726     IDirect3D9_Release(d3d);
9727 }
9728
9729 static void texop_range_test(IDirect3DDevice9 *device)
9730 {
9731     static const struct {
9732         float x, y, z;
9733         D3DCOLOR diffuse;
9734     } quad[] = {
9735         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9736         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9737         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9738         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9739     };
9740     HRESULT hr;
9741     IDirect3DTexture9 *texture;
9742     D3DLOCKED_RECT locked_rect;
9743     D3DCAPS9 caps;
9744     DWORD color;
9745
9746     /* We need ADD and SUBTRACT operations */
9747     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9748     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9749     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9750         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9751         return;
9752     }
9753     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9754         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9755         return;
9756     }
9757
9758     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9759     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9760     /* Stage 1: result = diffuse(=1.0) + diffuse
9761      * stage 2: result = result - tfactor(= 0.5)
9762      */
9763     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9764     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9765     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9766     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9767     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9768     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9769     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9770     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9771     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9772     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9773     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9774     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9775     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9776     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9777
9778     hr = IDirect3DDevice9_BeginScene(device);
9779     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9780     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9781     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9782     hr = IDirect3DDevice9_EndScene(device);
9783     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9784
9785     color = getPixelColor(device, 320, 240);
9786     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9787        color);
9788     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9789     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9790
9791     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9792     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9793     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9794     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9795     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9796     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9797     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9798     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9799     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9800
9801     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9802      * stage 2: result = result + diffuse(1.0)
9803      */
9804     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9805     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9806     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9807     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9808     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9809     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9810     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9811     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9812     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9813     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9814     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9815     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9816     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9817     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9818
9819     hr = IDirect3DDevice9_BeginScene(device);
9820     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9821     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9822     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9823     hr = IDirect3DDevice9_EndScene(device);
9824     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9825
9826     color = getPixelColor(device, 320, 240);
9827     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9828        color);
9829     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9830     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9831
9832     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9833     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9834     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9835     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9836     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9837     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9838     IDirect3DTexture9_Release(texture);
9839 }
9840
9841 static void alphareplicate_test(IDirect3DDevice9 *device) {
9842     struct vertex quad[] = {
9843         { -1.0,    -1.0,    0.1,    0x80ff00ff },
9844         {  1.0,    -1.0,    0.1,    0x80ff00ff },
9845         { -1.0,     1.0,    0.1,    0x80ff00ff },
9846         {  1.0,     1.0,    0.1,    0x80ff00ff },
9847     };
9848     HRESULT hr;
9849     DWORD color;
9850
9851     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9852     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9853
9854     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9855     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9856
9857     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9858     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9859     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9860     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9861
9862     hr = IDirect3DDevice9_BeginScene(device);
9863     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9864     if(SUCCEEDED(hr)) {
9865         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9866         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9867         hr = IDirect3DDevice9_EndScene(device);
9868         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9869     }
9870
9871     color = getPixelColor(device, 320, 240);
9872     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9873        color);
9874     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9875     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9876
9877     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9878     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9879
9880 }
9881
9882 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9883     HRESULT hr;
9884     D3DCAPS9 caps;
9885     DWORD color;
9886     struct vertex quad[] = {
9887         { -1.0,    -1.0,    0.1,    0x408080c0 },
9888         {  1.0,    -1.0,    0.1,    0x408080c0 },
9889         { -1.0,     1.0,    0.1,    0x408080c0 },
9890         {  1.0,     1.0,    0.1,    0x408080c0 },
9891     };
9892
9893     memset(&caps, 0, sizeof(caps));
9894     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9895     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9896     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9897         skip("D3DTOP_DOTPRODUCT3 not supported\n");
9898         return;
9899     }
9900
9901     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9902     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9903
9904     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9905     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9906
9907     /* dp3_x4 r0, diffuse_bias, tfactor_bias
9908      * mov r0.a, diffuse.a
9909      * mov r0, r0.a
9910      *
9911      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9912      * thus with input vec4(0.5, 0.5, 0.75, 0.25) and vec4(1.0, 1.0, 1.0, 1.0) the result is
9913      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9914      */
9915     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9916     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9917     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9918     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9919     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9920     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9921     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9922     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9923     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9924     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9925     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9926     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9927     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9928     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9929     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9930     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9931     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9932     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9933
9934     hr = IDirect3DDevice9_BeginScene(device);
9935     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9936     if(SUCCEEDED(hr)) {
9937         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9938         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9939         hr = IDirect3DDevice9_EndScene(device);
9940         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9941     }
9942
9943     color = getPixelColor(device, 320, 240);
9944     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9945        color);
9946     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9947     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9948
9949     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9950     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9951     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9952     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9953     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9954     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9955 }
9956
9957 static void zwriteenable_test(IDirect3DDevice9 *device) {
9958     HRESULT hr;
9959     DWORD color;
9960     struct vertex quad1[] = {
9961         { -1.0,  -1.0,  0.1,    0x00ff0000},
9962         { -1.0,   1.0,  0.1,    0x00ff0000},
9963         {  1.0,  -1.0,  0.1,    0x00ff0000},
9964         {  1.0,   1.0,  0.1,    0x00ff0000},
9965     };
9966     struct vertex quad2[] = {
9967         { -1.0,  -1.0,  0.9,    0x0000ff00},
9968         { -1.0,   1.0,  0.9,    0x0000ff00},
9969         {  1.0,  -1.0,  0.9,    0x0000ff00},
9970         {  1.0,   1.0,  0.9,    0x0000ff00},
9971     };
9972
9973     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9974     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9975
9976     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9977     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9978     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9979     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9980     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
9981     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9982     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
9983     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9984
9985     hr = IDirect3DDevice9_BeginScene(device);
9986     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9987     if(SUCCEEDED(hr)) {
9988         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
9989          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
9990          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
9991          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
9992          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
9993          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
9994          */
9995         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
9996         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9997         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
9998         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9999         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10000         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10001
10002         hr = IDirect3DDevice9_EndScene(device);
10003         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10004     }
10005
10006     color = getPixelColor(device, 320, 240);
10007     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10008        color);
10009     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10010     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10011
10012     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10013     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10014 }
10015
10016 static void alphatest_test(IDirect3DDevice9 *device) {
10017 #define ALPHATEST_PASSED 0x0000ff00
10018 #define ALPHATEST_FAILED 0x00ff0000
10019     struct {
10020         D3DCMPFUNC  func;
10021         DWORD       color_less;
10022         DWORD       color_equal;
10023         DWORD       color_greater;
10024     } testdata[] = {
10025         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10026         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10027         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10028         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10029         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10030         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10031         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10032         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10033     };
10034     unsigned int i, j;
10035     HRESULT hr;
10036     DWORD color;
10037     struct vertex quad[] = {
10038         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10039         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10040         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10041         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10042     };
10043     D3DCAPS9 caps;
10044
10045     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10046     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10047     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10048     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10049
10050     for(j = 0; j < 2; j++) {
10051         if(j == 1) {
10052             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10053              * the alpha test either for performance reasons(floating point RTs) or to work
10054              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10055              * codepath for ffp and shader in this case, and the test should cover both
10056              */
10057             IDirect3DPixelShader9 *ps;
10058             DWORD shader_code[] = {
10059                 0xffff0101,                                 /* ps_1_1           */
10060                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10061                 0x0000ffff                                  /* end              */
10062             };
10063             memset(&caps, 0, sizeof(caps));
10064             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10065             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10066             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10067                 break;
10068             }
10069
10070             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10071             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10072             IDirect3DDevice9_SetPixelShader(device, ps);
10073             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10074             IDirect3DPixelShader9_Release(ps);
10075         }
10076
10077         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10078             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10079             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10080
10081             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10082             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10083             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10084             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10085             hr = IDirect3DDevice9_BeginScene(device);
10086             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10087             if(SUCCEEDED(hr)) {
10088                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10089                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10090                 hr = IDirect3DDevice9_EndScene(device);
10091                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10092             }
10093             color = getPixelColor(device, 320, 240);
10094             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10095             color, testdata[i].color_less, testdata[i].func);
10096             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10097             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10098
10099             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10100             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10101             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10102             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10103             hr = IDirect3DDevice9_BeginScene(device);
10104             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10105             if(SUCCEEDED(hr)) {
10106                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10107                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10108                 hr = IDirect3DDevice9_EndScene(device);
10109                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10110             }
10111             color = getPixelColor(device, 320, 240);
10112             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10113             color, testdata[i].color_equal, testdata[i].func);
10114             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10115             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10116
10117             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10118             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10119             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10120             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10121             hr = IDirect3DDevice9_BeginScene(device);
10122             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10123             if(SUCCEEDED(hr)) {
10124                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10125                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10126                 hr = IDirect3DDevice9_EndScene(device);
10127                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10128             }
10129             color = getPixelColor(device, 320, 240);
10130             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10131             color, testdata[i].color_greater, testdata[i].func);
10132             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10133             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10134         }
10135     }
10136
10137     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10138     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10139     IDirect3DDevice9_SetPixelShader(device, NULL);
10140     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10141 }
10142
10143 static void sincos_test(IDirect3DDevice9 *device) {
10144     const DWORD sin_shader_code[] = {
10145         0xfffe0200,                                                                 /* vs_2_0                       */
10146         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10147         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10148         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10149         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10150         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10151         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10152         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10153         0x0000ffff                                                                  /* end                          */
10154     };
10155     const DWORD cos_shader_code[] = {
10156         0xfffe0200,                                                                 /* vs_2_0                       */
10157         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10158         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10159         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10160         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10161         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10162         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10163         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10164         0x0000ffff                                                                  /* end                          */
10165     };
10166     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10167     HRESULT hr;
10168     struct {
10169         float x, y, z;
10170     } data[1280];
10171     unsigned int i;
10172     float sincosc1[4] = {D3DSINCOSCONST1};
10173     float sincosc2[4] = {D3DSINCOSCONST2};
10174
10175     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10176     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10177
10178     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10179     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10180     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10181     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10182     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10183     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10184     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10185     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10186     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10187     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10188
10189     /* Generate a point from -1 to 1 every 0.5 pixels */
10190     for(i = 0; i < 1280; i++) {
10191         data[i].x = (-640.0 + i) / 640.0;
10192         data[i].y = 0.0;
10193         data[i].z = 0.1;
10194     }
10195
10196     hr = IDirect3DDevice9_BeginScene(device);
10197     if(SUCCEEDED(hr)) {
10198         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10199         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10200         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10201         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10202
10203         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10204         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10205         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10206         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10207
10208         hr = IDirect3DDevice9_EndScene(device);
10209         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10210     }
10211     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10212     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10213     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10214
10215     IDirect3DDevice9_SetVertexShader(device, NULL);
10216     IDirect3DVertexShader9_Release(sin_shader);
10217     IDirect3DVertexShader9_Release(cos_shader);
10218 }
10219
10220 static void loop_index_test(IDirect3DDevice9 *device) {
10221     const DWORD shader_code[] = {
10222         0xfffe0200,                                                 /* vs_2_0                   */
10223         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10224         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10225         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10226         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10227         0x0000001d,                                                 /* endloop                  */
10228         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10229         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10230         0x0000ffff                                                  /* END                      */
10231     };
10232     IDirect3DVertexShader9 *shader;
10233     HRESULT hr;
10234     DWORD color;
10235     const float quad[] = {
10236         -1.0,   -1.0,   0.1,
10237          1.0,   -1.0,   0.1,
10238         -1.0,    1.0,   0.1,
10239          1.0,    1.0,   0.1
10240     };
10241     const float zero[4] = {0, 0, 0, 0};
10242     const float one[4] = {1, 1, 1, 1};
10243     int i0[4] = {2, 10, -3, 0};
10244     float values[4];
10245
10246     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10247     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10248     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10249     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10250     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10251     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10252     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10253     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10254
10255     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10256     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10257     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10258     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10259     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10260     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10261     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10262     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10263     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10264     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10265     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10266     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10267     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10268     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10269     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10270     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10271     values[0] = 1.0;
10272     values[1] = 1.0;
10273     values[2] = 0.0;
10274     values[3] = 0.0;
10275     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10276     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10277     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10278     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10279     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10280     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10281     values[0] = -1.0;
10282     values[1] = 0.0;
10283     values[2] = 0.0;
10284     values[3] = 0.0;
10285     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10286     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10287     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10288     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10289     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10290     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10291     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10292     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10293     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10294     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10295
10296     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10297     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10298
10299     hr = IDirect3DDevice9_BeginScene(device);
10300     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10301     if(SUCCEEDED(hr))
10302     {
10303         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10304         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10305         hr = IDirect3DDevice9_EndScene(device);
10306         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10307     }
10308     color = getPixelColor(device, 320, 240);
10309     ok(color_match(color, 0x0000ff00, 1),
10310        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10311     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10312     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10313
10314     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10315     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10316     IDirect3DVertexShader9_Release(shader);
10317 }
10318
10319 static void sgn_test(IDirect3DDevice9 *device) {
10320     const DWORD shader_code[] = {
10321         0xfffe0200,                                                             /* vs_2_0                       */
10322         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10323         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10324         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10325         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10326         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10327         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10328         0x0000ffff                                                              /* end                          */
10329     };
10330     IDirect3DVertexShader9 *shader;
10331     HRESULT hr;
10332     DWORD color;
10333     const float quad[] = {
10334         -1.0,   -1.0,   0.1,
10335          1.0,   -1.0,   0.1,
10336         -1.0,    1.0,   0.1,
10337          1.0,    1.0,   0.1
10338     };
10339
10340     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10341     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10342     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10343     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10344     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10345     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10346     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10347     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10348
10349     hr = IDirect3DDevice9_BeginScene(device);
10350     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10351     if(SUCCEEDED(hr))
10352     {
10353         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10354         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10355         hr = IDirect3DDevice9_EndScene(device);
10356         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10357     }
10358     color = getPixelColor(device, 320, 240);
10359     ok(color_match(color, 0x008000ff, 1),
10360        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10361     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10362     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10363
10364     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10365     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10366     IDirect3DVertexShader9_Release(shader);
10367 }
10368
10369 static void viewport_test(IDirect3DDevice9 *device) {
10370     HRESULT hr;
10371     DWORD color;
10372     D3DVIEWPORT9 vp, old_vp;
10373     BOOL draw_failed = TRUE;
10374     const float quad[] =
10375     {
10376         -0.5,   -0.5,   0.1,
10377          0.5,   -0.5,   0.1,
10378         -0.5,    0.5,   0.1,
10379          0.5,    0.5,   0.1
10380     };
10381
10382     memset(&old_vp, 0, sizeof(old_vp));
10383     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10384     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10385
10386     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10387     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10388
10389     /* Test a viewport with Width and Height bigger than the surface dimensions
10390      *
10391      * TODO: Test Width < surface.width, but X + Width > surface.width
10392      * TODO: Test Width < surface.width, what happens with the height?
10393      *
10394      * Note that Windows 7 rejects MinZ / MaxZ outside [0;1], but accepts Width
10395      * and Height fields bigger than the framebuffer. However, it later refuses
10396      * to draw.
10397      */
10398     memset(&vp, 0, sizeof(vp));
10399     vp.X = 0;
10400     vp.Y = 0;
10401     vp.Width = 10000;
10402     vp.Height = 10000;
10403     vp.MinZ = 0.0;
10404     vp.MaxZ = 0.0;
10405     hr = IDirect3DDevice9_SetViewport(device, &vp);
10406     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10407
10408     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10409     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10410     hr = IDirect3DDevice9_BeginScene(device);
10411     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10412     if(SUCCEEDED(hr))
10413     {
10414         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10415         ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10416         draw_failed = FAILED(hr);
10417         hr = IDirect3DDevice9_EndScene(device);
10418         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10419     }
10420
10421     if(!draw_failed)
10422     {
10423         color = getPixelColor(device, 158, 118);
10424         ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10425         color = getPixelColor(device, 162, 118);
10426         ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10427         color = getPixelColor(device, 158, 122);
10428         ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10429         color = getPixelColor(device, 162, 122);
10430         ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10431
10432         color = getPixelColor(device, 478, 358);
10433         ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10434         color = getPixelColor(device, 482, 358);
10435         ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10436         color = getPixelColor(device, 478, 362);
10437         ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10438         color = getPixelColor(device, 482, 362);
10439         ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10440     }
10441
10442     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10443     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10444
10445     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10446     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10447 }
10448
10449 /* This test tests depth clamping / clipping behaviour:
10450  *   - When D3DRS_CLIPPING is disabled depth values are *clamped* to the
10451  *   minimum/maximum z value.
10452  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10453  *   - When D3DRS_CLIPPING is enabled depth values are clipped.
10454  *   - Pretransformed vertices behave the same as regular vertices.
10455  */
10456 static void depth_clamp_test(IDirect3DDevice9 *device)
10457 {
10458     const struct tvertex quad1[] =
10459     {
10460         {    0,    0,  5.0f, 1.0, 0xff002b7f},
10461         {  640,    0,  5.0f, 1.0, 0xff002b7f},
10462         {    0,  480,  5.0f, 1.0, 0xff002b7f},
10463         {  640,  480,  5.0f, 1.0, 0xff002b7f},
10464     };
10465     const struct tvertex quad2[] =
10466     {
10467         {    0,  300, 10.0f, 1.0, 0xfff9e814},
10468         {  640,  300, 10.0f, 1.0, 0xfff9e814},
10469         {    0,  360, 10.0f, 1.0, 0xfff9e814},
10470         {  640,  360, 10.0f, 1.0, 0xfff9e814},
10471     };
10472     const struct vertex quad3[] =
10473     {
10474         {-0.65, 0.55,  5.0f,      0xffffffff},
10475         {-0.35, 0.55,  5.0f,      0xffffffff},
10476         {-0.65, 0.15,  5.0f,      0xffffffff},
10477         {-0.35, 0.15,  5.0f,      0xffffffff},
10478     };
10479     const struct vertex quad4[] =
10480     {
10481         {-0.87, 0.83, 10.0f,      0xffffffff},
10482         {-0.65, 0.83, 10.0f,      0xffffffff},
10483         {-0.87, 0.55, 10.0f,      0xffffffff},
10484         {-0.65, 0.55, 10.0f,      0xffffffff},
10485     };
10486     const struct vertex quad5[] =
10487     {
10488         { -0.5,  0.5, 10.0f,      0xff14f914},
10489         {  0.5,  0.5, 10.0f,      0xff14f914},
10490         { -0.5, -0.5, 10.0f,      0xff14f914},
10491         {  0.5, -0.5, 10.0f,      0xff14f914},
10492     };
10493     const struct tvertex quad6[] =
10494     {
10495         {    0,  120, 10.0f, 1.0, 0xfff91414},
10496         {  640,  120, 10.0f, 1.0, 0xfff91414},
10497         {    0,  180, 10.0f, 1.0, 0xfff91414},
10498         {  640,  180, 10.0f, 1.0, 0xfff91414},
10499     };
10500
10501     D3DVIEWPORT9 vp;
10502     D3DCOLOR color;
10503     HRESULT hr;
10504
10505     vp.X = 0;
10506     vp.Y = 0;
10507     vp.Width = 640;
10508     vp.Height = 480;
10509     vp.MinZ = 0.0;
10510     vp.MaxZ = 7.5;
10511
10512     hr = IDirect3DDevice9_SetViewport(device, &vp);
10513     if(FAILED(hr))
10514     {
10515         /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10516          * the tests because the 7.5 is just intended to show that it doesn't have
10517          * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10518          * viewport and continue.
10519          */
10520         ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10521         vp.MaxZ = 1.0;
10522         hr = IDirect3DDevice9_SetViewport(device, &vp);
10523     }
10524     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10525
10526     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10527     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10528
10529     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10530     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10531     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10532     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10533     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10534     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10535     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10536     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10537
10538     hr = IDirect3DDevice9_BeginScene(device);
10539     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10540
10541     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10542     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10543
10544     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10545     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10546     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10547     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10548
10549     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10550     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10551
10552     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10553     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10554     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10555     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10556
10557     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10558     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10559
10560     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10561     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10562
10563     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10564     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10565
10566     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10567     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10568
10569     hr = IDirect3DDevice9_EndScene(device);
10570     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10571
10572     color = getPixelColor(device, 75, 75);
10573     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10574     color = getPixelColor(device, 150, 150);
10575     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10576     color = getPixelColor(device, 320, 240);
10577     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10578     color = getPixelColor(device, 320, 330);
10579     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10580     color = getPixelColor(device, 320, 330);
10581     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10582
10583     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10584     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10585
10586     vp.MinZ = 0.0;
10587     vp.MaxZ = 1.0;
10588     hr = IDirect3DDevice9_SetViewport(device, &vp);
10589     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10590 }
10591
10592 static void depth_bounds_test(IDirect3DDevice9 *device)
10593 {
10594     const struct tvertex quad1[] =
10595     {
10596         {    0,    0, 0.0f, 1, 0xfff9e814},
10597         {  640,    0, 0.0f, 1, 0xfff9e814},
10598         {    0,  480, 1.0f, 1, 0xfff9e814},
10599         {  640,  480, 1.0f, 1, 0xfff9e814},
10600     };
10601     const struct tvertex quad2[] =
10602     {
10603         {    0,    0,  0.6f, 1, 0xff002b7f},
10604         {  640,    0,  0.6f, 1, 0xff002b7f},
10605         {    0,  480,  0.6f, 1, 0xff002b7f},
10606         {  640,  480,  0.6f, 1, 0xff002b7f},
10607     };
10608     const struct tvertex quad3[] =
10609     {
10610         {    0,  100, 0.6f, 1, 0xfff91414},
10611         {  640,  100, 0.6f, 1, 0xfff91414},
10612         {    0,  160, 0.6f, 1, 0xfff91414},
10613         {  640,  160, 0.6f, 1, 0xfff91414},
10614     };
10615
10616     union {
10617         DWORD d;
10618         float f;
10619     } tmpvalue;
10620
10621     IDirect3D9 *d3d = NULL;
10622     IDirect3DSurface9 *offscreen_surface = NULL;
10623     D3DCOLOR color;
10624     HRESULT hr;
10625
10626     IDirect3DDevice9_GetDirect3D(device, &d3d);
10627     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10628             0,  D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
10629         skip("No NVDB (depth bounds test) support\n");
10630         IDirect3D9_Release(d3d);
10631         return;
10632     }
10633     IDirect3D9_Release(d3d);
10634
10635     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
10636             MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
10637     ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
10638     if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
10639
10640     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10641     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10642
10643     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10644     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10645     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
10646     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10647     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10648     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10649     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10650     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10651
10652
10653     hr = IDirect3DDevice9_BeginScene(device);
10654     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10655
10656     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10657     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10658
10659     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10660     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10661
10662     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
10663     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10664
10665     tmpvalue.f = 0.625;
10666     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10667     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10668
10669     tmpvalue.f = 0.75;
10670     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
10671     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10672
10673     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10674     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10675
10676     tmpvalue.f = 0.75;
10677     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10678     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10679
10680     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10681     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10682
10683     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
10684     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10685
10686     hr = IDirect3DDevice9_EndScene(device);
10687     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10688
10689     color = getPixelColor(device, 150, 130);
10690     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10691     color = getPixelColor(device, 150, 200);
10692     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10693     color = getPixelColor(device, 150, 300-5);
10694     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10695     color = getPixelColor(device, 150, 300+5);
10696     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10697     color = getPixelColor(device, 150, 330);
10698     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10699     color = getPixelColor(device, 150, 360-5);
10700     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10701     color = getPixelColor(device, 150, 360+5);
10702     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10703
10704     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10705     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10706 }
10707
10708 static void depth_buffer_test(IDirect3DDevice9 *device)
10709 {
10710     static const struct vertex quad1[] =
10711     {
10712         { -1.0,  1.0, 0.33f, 0xff00ff00},
10713         {  1.0,  1.0, 0.33f, 0xff00ff00},
10714         { -1.0, -1.0, 0.33f, 0xff00ff00},
10715         {  1.0, -1.0, 0.33f, 0xff00ff00},
10716     };
10717     static const struct vertex quad2[] =
10718     {
10719         { -1.0,  1.0, 0.50f, 0xffff00ff},
10720         {  1.0,  1.0, 0.50f, 0xffff00ff},
10721         { -1.0, -1.0, 0.50f, 0xffff00ff},
10722         {  1.0, -1.0, 0.50f, 0xffff00ff},
10723     };
10724     static const struct vertex quad3[] =
10725     {
10726         { -1.0,  1.0, 0.66f, 0xffff0000},
10727         {  1.0,  1.0, 0.66f, 0xffff0000},
10728         { -1.0, -1.0, 0.66f, 0xffff0000},
10729         {  1.0, -1.0, 0.66f, 0xffff0000},
10730     };
10731     static const DWORD expected_colors[4][4] =
10732     {
10733         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10734         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10735         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10736         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10737     };
10738
10739     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10740     unsigned int i, j;
10741     D3DVIEWPORT9 vp;
10742     D3DCOLOR color;
10743     HRESULT hr;
10744
10745     vp.X = 0;
10746     vp.Y = 0;
10747     vp.Width = 640;
10748     vp.Height = 480;
10749     vp.MinZ = 0.0;
10750     vp.MaxZ = 1.0;
10751
10752     hr = IDirect3DDevice9_SetViewport(device, &vp);
10753     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10754
10755     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10756     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10757     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10758     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10759     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10760     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10761     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10762     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10763     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10764     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10765
10766     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10767     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10768     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
10769             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10770     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10771     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10772             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10773     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10774     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10775             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
10776     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10777
10778     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
10779     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10780     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
10781     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10782
10783     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10784     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10785     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10786     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10787
10788     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
10789     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10790     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
10791     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10792
10793     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
10794     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10795     hr = IDirect3DDevice9_BeginScene(device);
10796     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10797     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10798     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10799     hr = IDirect3DDevice9_EndScene(device);
10800     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10801
10802     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10803     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10804     IDirect3DSurface9_Release(backbuffer);
10805     IDirect3DSurface9_Release(rt3);
10806     IDirect3DSurface9_Release(rt2);
10807     IDirect3DSurface9_Release(rt1);
10808
10809     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
10810     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10811
10812     hr = IDirect3DDevice9_BeginScene(device);
10813     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10814     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10815     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10816     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10817     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10818     hr = IDirect3DDevice9_EndScene(device);
10819     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10820
10821     for (i = 0; i < 4; ++i)
10822     {
10823         for (j = 0; j < 4; ++j)
10824         {
10825             unsigned int x = 80 * ((2 * j) + 1);
10826             unsigned int y = 60 * ((2 * i) + 1);
10827             color = getPixelColor(device, x, y);
10828             ok(color_match(color, expected_colors[i][j], 0),
10829                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
10830         }
10831     }
10832
10833     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10834     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10835 }
10836
10837 /* Test that partial depth copies work the way they're supposed to. The clear
10838  * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
10839  * the following draw should only copy back the part that was modified. */
10840 static void depth_buffer2_test(IDirect3DDevice9 *device)
10841 {
10842     static const struct vertex quad[] =
10843     {
10844         { -1.0,  1.0, 0.66f, 0xffff0000},
10845         {  1.0,  1.0, 0.66f, 0xffff0000},
10846         { -1.0, -1.0, 0.66f, 0xffff0000},
10847         {  1.0, -1.0, 0.66f, 0xffff0000},
10848     };
10849
10850     IDirect3DSurface9 *backbuffer, *rt1, *rt2;
10851     unsigned int i, j;
10852     D3DVIEWPORT9 vp;
10853     D3DCOLOR color;
10854     HRESULT hr;
10855
10856     vp.X = 0;
10857     vp.Y = 0;
10858     vp.Width = 640;
10859     vp.Height = 480;
10860     vp.MinZ = 0.0;
10861     vp.MaxZ = 1.0;
10862
10863     hr = IDirect3DDevice9_SetViewport(device, &vp);
10864     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10865
10866     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10867     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10868     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10869     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10870     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10871     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10872     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10873     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10874     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10875     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10876
10877     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10878             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10879     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10880     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10881             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10882     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10883     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10884     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10885
10886     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
10887     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10888     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10889     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10890
10891     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10892     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10893     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
10894     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10895
10896     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
10897     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10898     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
10899     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10900
10901     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10902     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10903     IDirect3DSurface9_Release(backbuffer);
10904     IDirect3DSurface9_Release(rt2);
10905     IDirect3DSurface9_Release(rt1);
10906
10907     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
10908     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10909
10910     hr = IDirect3DDevice9_BeginScene(device);
10911     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10912     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10913     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10914     hr = IDirect3DDevice9_EndScene(device);
10915     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10916
10917     for (i = 0; i < 4; ++i)
10918     {
10919         for (j = 0; j < 4; ++j)
10920         {
10921             unsigned int x = 80 * ((2 * j) + 1);
10922             unsigned int y = 60 * ((2 * i) + 1);
10923             color = getPixelColor(device, x, y);
10924             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
10925                     "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
10926         }
10927     }
10928
10929     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10930     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10931 }
10932
10933 static void depth_blit_test(IDirect3DDevice9 *device)
10934 {
10935     static const struct vertex quad1[] =
10936     {
10937         { -1.0,  1.0, 0.50f, 0xff00ff00},
10938         {  1.0,  1.0, 0.50f, 0xff00ff00},
10939         { -1.0, -1.0, 0.50f, 0xff00ff00},
10940         {  1.0, -1.0, 0.50f, 0xff00ff00},
10941     };
10942     static const struct vertex quad2[] =
10943     {
10944         { -1.0,  1.0, 0.66f, 0xff0000ff},
10945         {  1.0,  1.0, 0.66f, 0xff0000ff},
10946         { -1.0, -1.0, 0.66f, 0xff0000ff},
10947         {  1.0, -1.0, 0.66f, 0xff0000ff},
10948     };
10949     static const DWORD expected_colors[4][4] =
10950     {
10951         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10952         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10953         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10954         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10955     };
10956
10957     IDirect3DSurface9 *backbuffer, *ds1, *ds2;
10958     RECT src_rect, dst_rect;
10959     unsigned int i, j;
10960     D3DVIEWPORT9 vp;
10961     D3DCOLOR color;
10962     HRESULT hr;
10963
10964     vp.X = 0;
10965     vp.Y = 0;
10966     vp.Width = 640;
10967     vp.Height = 480;
10968     vp.MinZ = 0.0;
10969     vp.MaxZ = 1.0;
10970
10971     hr = IDirect3DDevice9_SetViewport(device, &vp);
10972     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10973
10974     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10975     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10976     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
10977     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
10978     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
10979     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
10980     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
10981     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
10982
10983     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10984     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10985     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10986     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10987     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10988     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10989     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10990     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10991
10992     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
10993     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10994     SetRect(&dst_rect, 0, 0, 480, 360);
10995     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
10996     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10997     SetRect(&dst_rect, 0, 0, 320, 240);
10998     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
10999     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11000
11001     /* Partial blit. */
11002     SetRect(&src_rect, 0, 0, 320, 240);
11003     SetRect(&dst_rect, 0, 0, 320, 240);
11004     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11005     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11006     /* Flipped. */
11007     SetRect(&src_rect, 0, 0, 640, 480);
11008     SetRect(&dst_rect, 0, 480, 640, 0);
11009     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11010     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11011     /* Full, explicit. */
11012     SetRect(&src_rect, 0, 0, 640, 480);
11013     SetRect(&dst_rect, 0, 0, 640, 480);
11014     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11015     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11016     /* Filtered blit. */
11017     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11018     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11019     /* Depth -> color blit.*/
11020     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11021     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11022     IDirect3DSurface9_Release(backbuffer);
11023
11024     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11025     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11026     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11027     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11028     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11029     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11030     IDirect3DSurface9_Release(ds2);
11031     IDirect3DSurface9_Release(ds1);
11032
11033     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11034     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11035     hr = IDirect3DDevice9_BeginScene(device);
11036     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11037     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11038     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11039     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11040     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11041     hr = IDirect3DDevice9_EndScene(device);
11042     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11043
11044     for (i = 0; i < 4; ++i)
11045     {
11046         for (j = 0; j < 4; ++j)
11047         {
11048             unsigned int x = 80 * ((2 * j) + 1);
11049             unsigned int y = 60 * ((2 * i) + 1);
11050             color = getPixelColor(device, x, y);
11051             ok(color_match(color, expected_colors[i][j], 0),
11052                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11053         }
11054     }
11055
11056     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11057     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11058 }
11059
11060 static void intz_test(IDirect3DDevice9 *device)
11061 {
11062     static const DWORD ps_code[] =
11063     {
11064         0xffff0200,                                                             /* ps_2_0                       */
11065         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11066         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11067         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11068         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11069         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11070         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11071         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11072         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11073         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11074         0x0000ffff,                                                             /* end                          */
11075     };
11076     struct
11077     {
11078         float x, y, z;
11079         float s, t, p, q;
11080     }
11081     quad[] =
11082     {
11083         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11084         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11085         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11086         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11087     };
11088     struct
11089     {
11090         UINT x, y;
11091         D3DCOLOR color;
11092     }
11093     expected_colors[] =
11094     {
11095         {400,  60, D3DCOLOR_ARGB(0x00, 0x9f, 0xff, 0x00)},
11096         {560, 180, D3DCOLOR_ARGB(0x00, 0xdf, 0x55, 0x00)},
11097         {560, 300, D3DCOLOR_ARGB(0x00, 0xdf, 0x66, 0x00)},
11098         {400, 420, D3DCOLOR_ARGB(0x00, 0x9f, 0xb6, 0x00)},
11099         {240, 420, D3DCOLOR_ARGB(0x00, 0x60, 0x6d, 0x00)},
11100         { 80, 300, D3DCOLOR_ARGB(0x00, 0x20, 0x33, 0x00)},
11101         { 80, 180, D3DCOLOR_ARGB(0x00, 0x20, 0x55, 0x00)},
11102         {240,  60, D3DCOLOR_ARGB(0x00, 0x60, 0xff, 0x00)},
11103     };
11104
11105     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11106     IDirect3DTexture9 *texture;
11107     IDirect3DPixelShader9 *ps;
11108     IDirect3DSurface9 *ds;
11109     IDirect3D9 *d3d9;
11110     D3DCAPS9 caps;
11111     HRESULT hr;
11112     UINT i;
11113
11114     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11115     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11116     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11117     {
11118         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11119         return;
11120     }
11121
11122     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11123     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11124
11125     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11126             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11127     if (FAILED(hr))
11128     {
11129         skip("No INTZ support, skipping INTZ test.\n");
11130         return;
11131     }
11132
11133     IDirect3D9_Release(d3d9);
11134
11135     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11136     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11137     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11138     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11139
11140     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11141             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11142     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11143     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11144             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11145     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11146     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11147     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11148
11149     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11150     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11151     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11152     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11153     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11154     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11155     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11156     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11157     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11158     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11159
11160     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11161     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11162     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11163     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11164     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11165     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11166     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11167     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11168     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11169     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11170
11171     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11172     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11173     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11174     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11175     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11176     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11177     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11178     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11179
11180     /* Setup the depth/stencil surface. */
11181     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11182     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11183
11184     hr = IDirect3DDevice9_BeginScene(device);
11185     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11186     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11187     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11188     hr = IDirect3DDevice9_EndScene(device);
11189     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11190
11191     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11192     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11193     IDirect3DSurface9_Release(ds);
11194     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11195     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11196     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11197     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11198     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11199     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11200
11201     /* Read the depth values back. */
11202     hr = IDirect3DDevice9_BeginScene(device);
11203     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11204     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11205     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11206     hr = IDirect3DDevice9_EndScene(device);
11207     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11208
11209     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11210     {
11211         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11212         ok(color_match(color, expected_colors[i].color, 1),
11213                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11214                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11215     }
11216
11217     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11218     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11219
11220     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11221     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11222     IDirect3DSurface9_Release(original_ds);
11223     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11224     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11225     IDirect3DTexture9_Release(texture);
11226     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11227     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11228     IDirect3DPixelShader9_Release(ps);
11229
11230     IDirect3DSurface9_Release(original_rt);
11231     IDirect3DSurface9_Release(rt);
11232 }
11233
11234 static void shadow_test(IDirect3DDevice9 *device)
11235 {
11236     static const DWORD ps_code[] =
11237     {
11238         0xffff0200,                                                             /* ps_2_0                       */
11239         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11240         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11241         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11242         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11243         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11244         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11245         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11246         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11247         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11248         0x0000ffff,                                                             /* end                          */
11249     };
11250     struct
11251     {
11252         D3DFORMAT format;
11253         const char *name;
11254     }
11255     formats[] =
11256     {
11257         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
11258         {D3DFMT_D32,            "D3DFMT_D32"},
11259         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
11260         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
11261         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
11262         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
11263         {D3DFMT_D16,            "D3DFMT_D16"},
11264         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
11265         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
11266     };
11267     struct
11268     {
11269         float x, y, z;
11270         float s, t, p, q;
11271     }
11272     quad[] =
11273     {
11274         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11275         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11276         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11277         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11278     };
11279     struct
11280     {
11281         UINT x, y;
11282         D3DCOLOR color;
11283     }
11284     expected_colors[] =
11285     {
11286         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11287         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11288         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11289         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11290         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11291         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11292         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11293         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11294     };
11295
11296     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11297     IDirect3DPixelShader9 *ps;
11298     IDirect3D9 *d3d9;
11299     D3DCAPS9 caps;
11300     HRESULT hr;
11301     UINT i;
11302
11303     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11304     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11305     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11306     {
11307         skip("No pixel shader 2.0 support, skipping shadow test.\n");
11308         return;
11309     }
11310
11311     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11312     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11313     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11314     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11315     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11316     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11317
11318     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11319             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11320     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11321     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11322     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11323
11324     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11325     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11326     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11327     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11328     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11329     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11330     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11331     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11332     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11333     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11334
11335     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11336     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11337     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11338     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11339     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11340     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11341     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11342     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11343     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11344     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11345
11346     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11347     {
11348         D3DFORMAT format = formats[i].format;
11349         IDirect3DTexture9 *texture;
11350         IDirect3DSurface9 *ds;
11351         unsigned int j;
11352
11353         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11354                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11355         if (FAILED(hr)) continue;
11356
11357         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11358                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11359         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11360
11361         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11362         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11363
11364         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11365         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11366
11367         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11368         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11369
11370         IDirect3DDevice9_SetPixelShader(device, NULL);
11371         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11372
11373         /* Setup the depth/stencil surface. */
11374         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11375         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11376
11377         hr = IDirect3DDevice9_BeginScene(device);
11378         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11379         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11380         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11381         hr = IDirect3DDevice9_EndScene(device);
11382         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11383
11384         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11385         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11386         IDirect3DSurface9_Release(ds);
11387
11388         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11389         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11390
11391         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11392         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11393
11394         hr = IDirect3DDevice9_SetPixelShader(device, ps);
11395         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11396
11397         /* Do the actual shadow mapping. */
11398         hr = IDirect3DDevice9_BeginScene(device);
11399         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11400         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11401         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11402         hr = IDirect3DDevice9_EndScene(device);
11403         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11404
11405         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11406         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11407         IDirect3DTexture9_Release(texture);
11408
11409         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11410         {
11411             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11412             ok(color_match(color, expected_colors[j].color, 0),
11413                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11414                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11415                     formats[i].name, color);
11416         }
11417
11418         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11419         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11420     }
11421
11422     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11423     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11424     IDirect3DPixelShader9_Release(ps);
11425
11426     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11427     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11428     IDirect3DSurface9_Release(original_ds);
11429
11430     IDirect3DSurface9_Release(original_rt);
11431     IDirect3DSurface9_Release(rt);
11432
11433     IDirect3D9_Release(d3d9);
11434 }
11435
11436 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
11437 {
11438     const struct vertex quad1[] =
11439     {
11440         {-1.0f, -1.0f, 0.0f, 0xfff9e814},
11441         { 1.0f, -1.0f, 0.0f, 0xfff9e814},
11442         {-1.0f,  1.0f, 0.0f, 0xfff9e814},
11443         { 1.0f,  1.0f, 0.0f, 0xfff9e814},
11444     };
11445     const struct vertex quad2[] =
11446     {
11447         {-1.0f, -1.0f, 0.0f, 0xff002b7f},
11448         { 1.0f, -1.0f, 0.0f, 0xff002b7f},
11449         {-1.0f,  1.0f, 0.0f, 0xff002b7f},
11450         { 1.0f,  1.0f, 0.0f, 0xff002b7f},
11451     };
11452     D3DCOLOR color;
11453     HRESULT hr;
11454
11455     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
11456     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11457
11458     hr = IDirect3DDevice9_BeginScene(device);
11459     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11460
11461     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11462     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11463
11464     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11465     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11466     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11467     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11468
11469     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
11470     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11471     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11472     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11473
11474     hr = IDirect3DDevice9_EndScene(device);
11475     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11476
11477     color = getPixelColor(device, 1, 240);
11478     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11479     color = getPixelColor(device, 638, 240);
11480     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11481
11482     color = getPixelColor(device, 1, 241);
11483     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11484     color = getPixelColor(device, 638, 241);
11485     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11486 }
11487
11488 static void clip_planes_test(IDirect3DDevice9 *device)
11489 {
11490     const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
11491
11492     const DWORD shader_code[] = {
11493         0xfffe0200, /* vs_2_0 */
11494         0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11495         0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11496         0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11497         0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11498         0x0000ffff /* end */
11499     };
11500     IDirect3DVertexShader9 *shader;
11501
11502     IDirect3DTexture9 *offscreen = NULL;
11503     IDirect3DSurface9 *offscreen_surface, *original_rt;
11504     HRESULT hr;
11505
11506     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11507     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11508
11509     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11510     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11511     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
11512     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11513     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11514     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11515     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11516     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11517
11518     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11519     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
11520     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11521     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
11522
11523     IDirect3DDevice9_SetClipPlane(device, 0, plane0);
11524
11525     clip_planes(device, "Onscreen FFP");
11526
11527     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
11528     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11529     hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
11530     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11531     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11532     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11533
11534     clip_planes(device, "Offscreen FFP");
11535
11536     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11537     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11538
11539     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11540     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
11541     IDirect3DDevice9_SetVertexShader(device, shader);
11542     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
11543
11544     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11545     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11546
11547     clip_planes(device, "Onscreen vertex shader");
11548
11549     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11550     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11551
11552     clip_planes(device, "Offscreen vertex shader");
11553
11554     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11555     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11556
11557     IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11558     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11559     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
11560     IDirect3DVertexShader9_Release(shader);
11561     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11562     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11563     IDirect3DSurface9_Release(original_rt);
11564     if (offscreen)
11565     {
11566         IDirect3DSurface9_Release(offscreen_surface);
11567         IDirect3DTexture9_Release(offscreen);
11568     }
11569 }
11570
11571 static void fp_special_test(IDirect3DDevice9 *device)
11572 {
11573     static const DWORD vs_header[] =
11574     {
11575         0xfffe0200,                                                             /* vs_2_0                       */
11576         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
11577         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
11578         0x0200001f, 0x80000005, 0x900f0001,                                     /* dcl_texcoord0 v1             */
11579     };
11580
11581     static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001};         /* log r0.x, v1.x               */
11582     static const DWORD vs_pow[] =
11583             {0x03000020, 0x80010000, 0x90000001, 0x90000001};                   /* pow r0.x, v1.x, v1.x         */
11584     static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001};         /* nrm r0.xyz, v1.x             */
11585     static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001};        /* rcp r0.x, v1.x               */
11586     static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001};        /* rcp r0.x, -v1.x              */
11587     static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001};        /* rsq r0.x, v1.x               */
11588     static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001};        /* rsq r0.x, -v1.x              */
11589
11590     static const DWORD vs_footer[] =
11591     {
11592         0x03000005, 0x80020000, 0x80000000, 0xa0ff0000,                         /* mul r0.y, r0.x, c0.w         */
11593         0x0300000d, 0x80040000, 0x80000000, 0x80550000,                         /* sge r0.z, r0.x, r0.y         */
11594         0x0300000d, 0x80020000, 0x80e40000, 0x80000000,                         /* sge r0.y, r0, r0.x           */
11595         0x03000005, 0x80040000, 0x80550000, 0x80e40000,                         /* mul r0.z, r0.y, r0           */
11596         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
11597         0x0300000c, 0x80020000, 0x80000000, 0x80000000,                         /* slt r0.y, r0.x, r0.x         */
11598         0x03000002, 0x80040000, 0x80550000, 0x80550000,                         /* add r0.z, r0.y, r0.y         */
11599         0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000,                         /* slt r0.y, c0.x, r0.w         */
11600         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
11601         0x03000002, 0x80040000, 0x81550000, 0xa0e40000,                         /* add r0.z, -r0.y, c0          */
11602         0x0300000c, 0x80080000, 0xa0000000, 0x80e40000,                         /* slt r0.w, c0.x, r0           */
11603         0x03000005, 0x80040000, 0x80ff0000, 0x80e40000,                         /* mul r0.z, r0.w, r0           */
11604         0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000,             /* mad r0.y, r0.z, c0, r0       */
11605         0x02000001, 0xe0030000, 0x80e40000,                                     /* mov oT0.xy, r0               */
11606         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
11607         0x0000ffff,                                                             /* end                          */
11608     };
11609
11610     static const struct
11611     {
11612         const char *name;
11613         const DWORD *ops;
11614         DWORD size;
11615         D3DCOLOR r600;
11616         D3DCOLOR nv40;
11617         D3DCOLOR nv50;
11618     }
11619     vs_body[] =
11620     {
11621         /* The basic ideas here are:
11622          *     2.0 * +/-INF == +/-INF
11623          *     NAN != NAN
11624          *
11625          * The vertex shader value is written to the red component, with 0.0
11626          * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
11627          * result in 0x00. The pixel shader value is written to the green
11628          * component, but here 0.0 also results in 0x00. The actual value is
11629          * written to the blue component.
11630          *
11631          * There are considerable differences between graphics cards in how
11632          * these are handled, but pow and nrm never generate INF or NAN. */
11633         {"log",     vs_log,     sizeof(vs_log),     0x00000000, 0x00ff0000, 0x00ff7f00},
11634         {"pow",     vs_pow,     sizeof(vs_pow),     0x000000ff, 0x0000ff00, 0x000000ff},
11635         {"nrm",     vs_nrm,     sizeof(vs_nrm),     0x00ff0000, 0x0000ff00, 0x00ff0000},
11636         {"rcp1",    vs_rcp1,    sizeof(vs_rcp1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
11637         {"rcp2",    vs_rcp2,    sizeof(vs_rcp2),    0x00000000, 0x00ff0000, 0x00ff7f00},
11638         {"rsq1",    vs_rsq1,    sizeof(vs_rsq1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
11639         {"rsq2",    vs_rsq2,    sizeof(vs_rsq2),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
11640     };
11641
11642     static const DWORD ps_code[] =
11643     {
11644         0xffff0200,                                                             /* ps_2_0                       */
11645         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
11646         0x0200001f, 0x80000000, 0xb0030000,                                     /* dcl t0.xy                    */
11647         0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000,                         /* max r1.x, t0, c0             */
11648         0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000,                         /* min r0.x, t0, c0             */
11649         0x03000002, 0x80010000, 0x80e40000, 0x81e40001,                         /* add r0.x, r0, -r1            */
11650         0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000,             /* mad r1.x, t0, c0.w. -t0      */
11651         0x02000023, 0x80010002, 0x80e40001,                                     /* abs r2.x, r1                 */
11652         0x02000023, 0x80010000, 0x80e40000,                                     /* abs r0.x, r0                 */
11653         0x02000023, 0x80010001, 0xb0e40000,                                     /* abs r1.x, t0                 */
11654         0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r2, c0.z, c0      */
11655         0x02000023, 0x80010002, 0x80e40002,                                     /* abs r2.x, r2                 */
11656         0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r1.x, -r1, c0.z, c0      */
11657         0x02000023, 0x80010001, 0x80e40001,                                     /* abs r1.x, r1                 */
11658         0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r3.x, -r2, c0.z, c0      */
11659         0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r1, c0.z, c0      */
11660         0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000,             /* cmp r0.x, -r0, c0.y, c0      */
11661         0x03000005, 0x80010002, 0x80e40002, 0x80e40003,                         /* mul r2.x, r2, r3             */
11662         0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000,             /* cmp r0.x, -r2, c0.z, r0      */
11663         0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000,             /* cmp r0.y, -r1.x, r0.x, c0.x  */
11664         0x02000001, 0x80050000, 0xb0c90000,                                     /* mov r0.xz, t0.yzxw           */
11665         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.w, c0.z               */
11666         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
11667         0x0000ffff,                                                             /* end                          */
11668     };
11669
11670     struct
11671     {
11672         float x, y, z;
11673         float s;
11674     }
11675     quad[] =
11676     {
11677         { -1.0f,  1.0f, 0.0f, 0.0f},
11678         {  1.0f,  1.0f, 1.0f, 0.0f},
11679         { -1.0f, -1.0f, 0.0f, 0.0f},
11680         {  1.0f, -1.0f, 1.0f, 0.0f},
11681     };
11682
11683     IDirect3DPixelShader9 *ps;
11684     UINT body_size = 0;
11685     DWORD *vs_code;
11686     D3DCAPS9 caps;
11687     HRESULT hr;
11688     UINT i;
11689
11690     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11691     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11692     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
11693     {
11694         skip("No shader model 2.0 support, skipping floating point specials test.\n");
11695         return;
11696     }
11697
11698     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
11699     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11700
11701     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11702     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11703     IDirect3DDevice9_SetPixelShader(device, ps);
11704     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11705
11706     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11707     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11708
11709     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11710     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11711
11712     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11713     {
11714         if (vs_body[i].size > body_size) body_size = vs_body[i].size;
11715     }
11716
11717     vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
11718     memcpy(vs_code, vs_header, sizeof(vs_header));
11719
11720     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11721     {
11722         DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
11723         IDirect3DVertexShader9 *vs;
11724         D3DCOLOR color;
11725
11726         memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
11727         offset += vs_body[i].size / sizeof(*vs_body[i].ops);
11728         memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
11729
11730         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
11731         ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11732         IDirect3DDevice9_SetVertexShader(device, vs);
11733         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11734
11735         hr = IDirect3DDevice9_BeginScene(device);
11736         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11737         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11738         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11739         hr = IDirect3DDevice9_EndScene(device);
11740         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11741
11742         color = getPixelColor(device, 320, 240);
11743         ok(color_match(color, vs_body[i].r600, 1)
11744                 || color_match(color, vs_body[i].nv40, 1)
11745                 || color_match(color, vs_body[i].nv50, 1),
11746                 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
11747                 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
11748
11749         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11750         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11751
11752         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11753         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11754         IDirect3DVertexShader9_Release(vs);
11755     }
11756
11757     HeapFree(GetProcessHeap(), 0, vs_code);
11758
11759     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11760     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11761     IDirect3DPixelShader9_Release(ps);
11762 }
11763
11764 static void srgbwrite_format_test(IDirect3DDevice9 *device)
11765 {
11766     IDirect3D9 *d3d;
11767     IDirect3DSurface9 *rt, *backbuffer;
11768     IDirect3DTexture9 *texture;
11769     HRESULT hr;
11770     int i;
11771     DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
11772     static const struct
11773     {
11774         D3DFORMAT fmt;
11775         const char *name;
11776     }
11777     formats[] =
11778     {
11779         { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
11780         { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
11781         { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
11782         { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
11783         { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
11784     };
11785     static const struct
11786     {
11787         float x, y, z;
11788         float u, v;
11789     }
11790     quad[] =
11791     {
11792         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
11793         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
11794         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
11795         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
11796     };
11797
11798     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
11799     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11800     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11801     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11802     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11803     ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
11804     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11805     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11806     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
11807     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11808
11809     for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
11810     {
11811         if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11812                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
11813         {
11814             skip("Format %s not supported as render target, skipping test.\n",
11815                     formats[i].name);
11816             continue;
11817         }
11818
11819         hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
11820                                             D3DPOOL_DEFAULT, &texture, NULL);
11821         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11822         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
11823         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11824
11825         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
11826         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11827         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11828         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11829         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
11830         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11831
11832         hr = IDirect3DDevice9_BeginScene(device);
11833         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11834         if(SUCCEEDED(hr))
11835         {
11836             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
11837             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11838             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
11839             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11840             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11841             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
11842
11843             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
11844             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11845             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11846             ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11847             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
11848             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11849             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11850             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11851             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11852             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
11853             hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11854             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11855
11856             hr = IDirect3DDevice9_EndScene(device);
11857             ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11858         }
11859
11860         IDirect3DSurface9_Release(rt);
11861         IDirect3DTexture9_Release(texture);
11862
11863         color = getPixelColor(device, 360, 240);
11864         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11865                                     D3DUSAGE_QUERY_SRGBWRITE,
11866                                     D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
11867         {
11868             /* Big slop for R5G6B5 */
11869             ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
11870                 formats[i].name, color_srgb, color);
11871         }
11872         else
11873         {
11874             /* Big slop for R5G6B5 */
11875             ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
11876                 formats[i].name, color_rgb, color);
11877         }
11878
11879         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11880         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11881     }
11882
11883     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
11884     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11885
11886     IDirect3D9_Release(d3d);
11887     IDirect3DSurface9_Release(backbuffer);
11888 }
11889
11890 static void ds_size_test(IDirect3DDevice9 *device)
11891 {
11892     IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
11893     HRESULT hr;
11894     DWORD color;
11895     DWORD num_passes;
11896     struct
11897     {
11898         float x, y, z;
11899     }
11900     quad[] =
11901     {
11902         {-1.0,  -1.0,   0.0 },
11903         {-1.0,   1.0,   0.0 },
11904         { 1.0,  -1.0,   0.0 },
11905         { 1.0,   1.0,   0.0 }
11906     };
11907
11908     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11909     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
11910     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
11911     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
11912     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
11913     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
11914
11915     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
11916     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
11917     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
11918     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
11919     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11920     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
11921     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
11922     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
11923     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
11924     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
11925     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
11926     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
11927     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11928     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
11929     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11930     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
11931     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
11932     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
11933
11934     /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
11935      * but does not change the surface's contents. */
11936     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
11937     ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
11938     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
11939     ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
11940     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
11941     ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
11942
11943     hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
11944     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTargetData failed, hr %#x.\n", hr);
11945     color = getPixelColorFromSurface(readback, 2, 2);
11946     ok(color == 0x000000FF, "DS size test: Pixel (2, 2) after clear is %#x, expected 0x000000FF\n", color);
11947     color = getPixelColorFromSurface(readback, 31, 31);
11948     ok(color == 0x000000FF, "DS size test: Pixel (31, 31) after clear is %#x, expected 0x000000FF\n", color);
11949     color = getPixelColorFromSurface(readback, 32, 32);
11950     ok(color == 0x000000FF, "DS size test: Pixel (32, 32) after clear is %#x, expected 0x000000FF\n", color);
11951     color = getPixelColorFromSurface(readback, 63, 63);
11952     ok(color == 0x000000FF, "DS size test: Pixel (63, 63) after clear is %#x, expected 0x000000FF\n", color);
11953
11954     /* Turning on any depth-related state results in a ValidateDevice failure */
11955     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11956     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
11957     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
11958     ok(hr == D3DERR_CONFLICTINGRENDERSTATE, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
11959         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
11960     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11961     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
11962     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11963     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
11964     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
11965     ok(hr == D3DERR_CONFLICTINGRENDERSTATE, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
11966         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
11967
11968     /* Try to draw with the device in an invalid state */
11969     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11970     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
11971     hr = IDirect3DDevice9_BeginScene(device);
11972     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
11973     if(SUCCEEDED(hr))
11974     {
11975         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11976         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
11977         hr = IDirect3DDevice9_EndScene(device);
11978         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
11979     }
11980
11981     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
11982     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
11983     hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
11984     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
11985     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
11986     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
11987
11988     IDirect3DSurface9_Release(readback);
11989     IDirect3DSurface9_Release(ds);
11990     IDirect3DSurface9_Release(rt);
11991     IDirect3DSurface9_Release(old_rt);
11992     IDirect3DSurface9_Release(old_ds);
11993 }
11994
11995 START_TEST(visual)
11996 {
11997     IDirect3DDevice9 *device_ptr;
11998     D3DCAPS9 caps;
11999     HRESULT hr;
12000     DWORD color;
12001
12002     d3d9_handle = LoadLibraryA("d3d9.dll");
12003     if (!d3d9_handle)
12004     {
12005         skip("Could not load d3d9.dll\n");
12006         return;
12007     }
12008
12009     device_ptr = init_d3d9();
12010     if (!device_ptr)
12011     {
12012         skip("Creating the device failed\n");
12013         return;
12014     }
12015
12016     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
12017
12018     /* Check for the reliability of the returned data */
12019     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
12020     if(FAILED(hr))
12021     {
12022         skip("Clear failed, can't assure correctness of the test results, skipping\n");
12023         goto cleanup;
12024     }
12025
12026     color = getPixelColor(device_ptr, 1, 1);
12027     if(color !=0x00ff0000)
12028     {
12029         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12030         goto cleanup;
12031     }
12032     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12033
12034     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
12035     if(FAILED(hr))
12036     {
12037         skip("Clear failed, can't assure correctness of the test results, skipping\n");
12038         goto cleanup;
12039     }
12040
12041     color = getPixelColor(device_ptr, 639, 479);
12042     if(color != 0x0000ddee)
12043     {
12044         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12045         goto cleanup;
12046     }
12047     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12048
12049     /* Now execute the real tests */
12050     depth_clamp_test(device_ptr);
12051     stretchrect_test(device_ptr);
12052     lighting_test(device_ptr);
12053     clear_test(device_ptr);
12054     color_fill_test(device_ptr);
12055     fog_test(device_ptr);
12056     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
12057     {
12058         test_cube_wrap(device_ptr);
12059     } else {
12060         skip("No cube texture support\n");
12061     }
12062     z_range_test(device_ptr);
12063     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
12064     {
12065         maxmip_test(device_ptr);
12066     }
12067     else
12068     {
12069         skip("No mipmap support\n");
12070     }
12071     offscreen_test(device_ptr);
12072     ds_size_test(device_ptr);
12073     alpha_test(device_ptr);
12074     shademode_test(device_ptr);
12075     srgbtexture_test(device_ptr);
12076     release_buffer_test(device_ptr);
12077     float_texture_test(device_ptr);
12078     g16r16_texture_test(device_ptr);
12079     pixelshader_blending_test(device_ptr);
12080     texture_transform_flags_test(device_ptr);
12081     autogen_mipmap_test(device_ptr);
12082     fixed_function_decl_test(device_ptr);
12083     conditional_np2_repeat_test(device_ptr);
12084     fixed_function_bumpmap_test(device_ptr);
12085     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
12086         stencil_cull_test(device_ptr);
12087     } else {
12088         skip("No two sided stencil support\n");
12089     }
12090     pointsize_test(device_ptr);
12091     tssargtemp_test(device_ptr);
12092     np2_stretch_rect_test(device_ptr);
12093     yuv_color_test(device_ptr);
12094     zwriteenable_test(device_ptr);
12095     alphatest_test(device_ptr);
12096     viewport_test(device_ptr);
12097
12098     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
12099     {
12100         test_constant_clamp_vs(device_ptr);
12101         test_compare_instructions(device_ptr);
12102     }
12103     else skip("No vs_1_1 support\n");
12104
12105     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
12106     {
12107         test_mova(device_ptr);
12108         loop_index_test(device_ptr);
12109         sincos_test(device_ptr);
12110         sgn_test(device_ptr);
12111         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12112             test_vshader_input(device_ptr);
12113             test_vshader_float16(device_ptr);
12114             stream_test(device_ptr);
12115         } else {
12116             skip("No vs_3_0 support\n");
12117         }
12118     }
12119     else skip("No vs_2_0 support\n");
12120
12121     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12122     {
12123         fog_with_shader_test(device_ptr);
12124     }
12125     else skip("No vs_1_1 and ps_1_1 support\n");
12126
12127     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12128     {
12129         texbem_test(device_ptr);
12130         texdepth_test(device_ptr);
12131         texkill_test(device_ptr);
12132         x8l8v8u8_test(device_ptr);
12133         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
12134             constant_clamp_ps_test(device_ptr);
12135             cnd_test(device_ptr);
12136             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
12137                 dp2add_ps_test(device_ptr);
12138                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12139                     nested_loop_test(device_ptr);
12140                     fixed_function_varying_test(device_ptr);
12141                     vFace_register_test(device_ptr);
12142                     vpos_register_test(device_ptr);
12143                     multiple_rendertargets_test(device_ptr);
12144                 } else {
12145                     skip("No ps_3_0 or vs_3_0 support\n");
12146                 }
12147             } else {
12148                 skip("No ps_2_0 support\n");
12149             }
12150         }
12151     }
12152     else skip("No ps_1_1 support\n");
12153
12154     texop_test(device_ptr);
12155     texop_range_test(device_ptr);
12156     alphareplicate_test(device_ptr);
12157     dp3_alpha_test(device_ptr);
12158     depth_buffer_test(device_ptr);
12159     depth_buffer2_test(device_ptr);
12160     depth_blit_test(device_ptr);
12161     intz_test(device_ptr);
12162     shadow_test(device_ptr);
12163     fp_special_test(device_ptr);
12164     depth_bounds_test(device_ptr);
12165     srgbwrite_format_test(device_ptr);
12166     clip_planes_test(device_ptr);
12167
12168 cleanup:
12169     if(device_ptr) {
12170         D3DPRESENT_PARAMETERS present_parameters;
12171         IDirect3DSwapChain9 *swapchain;
12172         ULONG ref;
12173
12174         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
12175         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
12176         IDirect3DSwapChain9_Release(swapchain);
12177         ref = IDirect3DDevice9_Release(device_ptr);
12178         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
12179         DestroyWindow(present_parameters.hDeviceWindow);
12180     }
12181 }