Release 1.4.1.
[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 struct vec3
38 {
39     float x, y, z;
40 };
41
42 struct vec4
43 {
44     float x, y, z, w;
45 };
46
47 static HWND create_window(void)
48 {
49     WNDCLASS wc = {0};
50     HWND ret;
51     wc.lpfnWndProc = DefWindowProc;
52     wc.lpszClassName = "d3d9_test_wc";
53     RegisterClass(&wc);
54
55     ret = CreateWindow("d3d9_test_wc", "d3d9_test",
56                         WS_SYSMENU | WS_POPUP , 0, 0, 640, 480, 0, 0, 0, 0);
57     ShowWindow(ret, SW_SHOW);
58     return ret;
59 }
60
61 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
62 {
63     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
64     c1 >>= 8; c2 >>= 8;
65     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
66     c1 >>= 8; c2 >>= 8;
67     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
68     c1 >>= 8; c2 >>= 8;
69     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
70     return TRUE;
71 }
72
73 /* Locks a given surface and returns the color at (x,y).  It's the caller's
74  * responsibility to only pass in lockable surfaces and valid x,y coordinates */
75 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
76 {
77     DWORD color;
78     HRESULT hr;
79     D3DSURFACE_DESC desc;
80     RECT rectToLock = {x, y, x+1, y+1};
81     D3DLOCKED_RECT lockedRect;
82
83     hr = IDirect3DSurface9_GetDesc(surface, &desc);
84     if(FAILED(hr))  /* This is not a test */
85     {
86         trace("Can't get the surface description, hr=%08x\n", hr);
87         return 0xdeadbeef;
88     }
89
90     hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
91     if(FAILED(hr))  /* This is not a test */
92     {
93         trace("Can't lock the surface, hr=%08x\n", hr);
94         return 0xdeadbeef;
95     }
96     switch(desc.Format) {
97         case D3DFMT_A8R8G8B8:
98         {
99             color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
100             break;
101         }
102         default:
103             trace("Error: unknown surface format: %d\n", desc.Format);
104             color = 0xdeadbeef;
105             break;
106     }
107     hr = IDirect3DSurface9_UnlockRect(surface);
108     if(FAILED(hr))
109     {
110         trace("Can't unlock the surface, hr=%08x\n", hr);
111     }
112     return color;
113 }
114
115 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
116 {
117     DWORD ret;
118     IDirect3DSurface9 *surf = NULL, *target = NULL;
119     HRESULT hr;
120     D3DLOCKED_RECT lockedRect;
121     RECT rectToLock = {x, y, x+1, y+1};
122
123     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480,
124             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
125     if (FAILED(hr) || !surf)
126     {
127         trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
128         return 0xdeadbeef;
129     }
130
131     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
132     if(FAILED(hr))
133     {
134         trace("Can't get the render target, hr=%08x\n", hr);
135         ret = 0xdeadbeed;
136         goto out;
137     }
138
139     hr = IDirect3DDevice9_GetRenderTargetData(device, target, surf);
140     if (FAILED(hr))
141     {
142         trace("Can't read the render target data, hr=%08x\n", hr);
143         ret = 0xdeadbeec;
144         goto out;
145     }
146
147     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
148     if(FAILED(hr))
149     {
150         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
151         ret = 0xdeadbeeb;
152         goto out;
153     }
154
155     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
156      * really important for these tests
157      */
158     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
159     hr = IDirect3DSurface9_UnlockRect(surf);
160     if(FAILED(hr))
161     {
162         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
163     }
164
165 out:
166     if(target) IDirect3DSurface9_Release(target);
167     if(surf) IDirect3DSurface9_Release(surf);
168     return ret;
169 }
170
171 static IDirect3DDevice9 *init_d3d9(void)
172 {
173     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
174     IDirect3D9 *d3d9_ptr = 0;
175     IDirect3DDevice9 *device_ptr = 0;
176     D3DPRESENT_PARAMETERS present_parameters;
177     HRESULT hr;
178     D3DADAPTER_IDENTIFIER9 identifier;
179
180     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
181     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
182     if (!d3d9_create) return NULL;
183
184     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
185     if (!d3d9_ptr)
186     {
187         win_skip("could not create D3D9\n");
188         return NULL;
189     }
190
191     ZeroMemory(&present_parameters, sizeof(present_parameters));
192     present_parameters.Windowed = TRUE;
193     present_parameters.hDeviceWindow = create_window();
194     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
195     present_parameters.BackBufferWidth = 640;
196     present_parameters.BackBufferHeight = 480;
197     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
198     present_parameters.EnableAutoDepthStencil = TRUE;
199     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
200
201     memset(&identifier, 0, sizeof(identifier));
202     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
203     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
204     trace("Driver string: \"%s\"\n", identifier.Driver);
205     trace("Description string: \"%s\"\n", identifier.Description);
206     ok(identifier.Description[0] != '\0', "Empty driver description\n");
207     trace("Device name string: \"%s\"\n", identifier.DeviceName);
208     ok(identifier.DeviceName[0]  != '\0', "Empty device name\n");
209     trace("Driver version %d.%d.%d.%d\n",
210           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
211           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
212
213     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
214             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
215     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
216             "Failed to create a device, hr %#x.\n", hr);
217
218     return device_ptr;
219 }
220
221 static void cleanup_device(IDirect3DDevice9 *device)
222 {
223     if (device)
224     {
225         D3DPRESENT_PARAMETERS present_parameters;
226         IDirect3DSwapChain9 *swapchain;
227         ULONG ref;
228
229         IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
230         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
231         IDirect3DSwapChain9_Release(swapchain);
232         ref = IDirect3DDevice9_Release(device);
233         ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
234         DestroyWindow(present_parameters.hDeviceWindow);
235     }
236 }
237
238 struct vertex
239 {
240     float x, y, z;
241     DWORD diffuse;
242 };
243
244 struct tvertex
245 {
246     float x, y, z, rhw;
247     DWORD diffuse;
248 };
249
250 struct nvertex
251 {
252     float x, y, z;
253     float nx, ny, nz;
254     DWORD diffuse;
255 };
256
257 static void lighting_test(IDirect3DDevice9 *device)
258 {
259     HRESULT hr;
260     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
261     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
262     DWORD color;
263     D3DMATERIAL9 material, old_material;
264     DWORD cop, carg;
265     DWORD old_colorwrite;
266
267     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
268                       0.0f, 1.0f, 0.0f, 0.0f,
269                       0.0f, 0.0f, 1.0f, 0.0f,
270                       0.0f, 0.0f, 0.0f, 1.0f };
271
272     struct vertex unlitquad[] =
273     {
274         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
275         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
276         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
277         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
278     };
279     struct vertex litquad[] =
280     {
281         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
282         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
283         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
284         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
285     };
286     struct nvertex unlitnquad[] =
287     {
288         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
289         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
290         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
291         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
292     };
293     struct nvertex litnquad[] =
294     {
295         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
296         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
297         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
298         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
299     };
300     WORD Indices[] = {0, 1, 2, 2, 3, 0};
301
302     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
303     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
304
305     /* Setup some states that may cause issues */
306     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
307     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
308     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
309     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
310     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
311     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
312     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
313     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
314     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
315     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
316     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
317     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
318     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
319     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
320     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
321     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
322     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
323     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
324     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
325     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
326     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
327     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
328     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &old_colorwrite);
329     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
330     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
331     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
332
333     hr = IDirect3DDevice9_SetFVF(device, 0);
334     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
335
336     hr = IDirect3DDevice9_SetFVF(device, fvf);
337     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
338
339     hr = IDirect3DDevice9_BeginScene(device);
340     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
341     if(hr == D3D_OK)
342     {
343         /* No lights are defined... That means, lit vertices should be entirely black */
344         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
345         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
346         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
347                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
348         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
349
350         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
351         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
352         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
353                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
354         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
355
356         hr = IDirect3DDevice9_SetFVF(device, nfvf);
357         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
358
359         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
360         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
361         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
362                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
363         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
364
365         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
366         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
367         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
368                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
369         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
370
371         IDirect3DDevice9_EndScene(device);
372         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
373     }
374
375     color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
376     ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
377     color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
378     ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
379     color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
380     ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
381     color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
382     ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
383
384     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
385
386     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
387     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
388     memset(&material, 0, sizeof(material));
389     material.Diffuse.r = 0.0;
390     material.Diffuse.g = 0.0;
391     material.Diffuse.b = 0.0;
392     material.Diffuse.a = 1.0;
393     material.Ambient.r = 0.0;
394     material.Ambient.g = 0.0;
395     material.Ambient.b = 0.0;
396     material.Ambient.a = 0.0;
397     material.Specular.r = 0.0;
398     material.Specular.g = 0.0;
399     material.Specular.b = 0.0;
400     material.Specular.a = 0.0;
401     material.Emissive.r = 0.0;
402     material.Emissive.g = 0.0;
403     material.Emissive.b = 0.0;
404     material.Emissive.a = 0.0;
405     material.Power = 0.0;
406     IDirect3DDevice9_SetMaterial(device, &material);
407     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
408
409     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
410     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
411     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
412     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
413
414     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
415     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
416     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
417     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
418     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
419     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
420     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
421     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
422
423     hr = IDirect3DDevice9_BeginScene(device);
424     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
425     if(SUCCEEDED(hr)) {
426         struct vertex lighting_test[] = {
427             {-1.0,   -1.0,   0.1,    0x8000ff00},
428             { 1.0,   -1.0,   0.1,    0x80000000},
429             {-1.0,    1.0,   0.1,    0x8000ff00},
430             { 1.0,    1.0,   0.1,    0x80000000}
431         };
432         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
433         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
434         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
435         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
436
437         hr = IDirect3DDevice9_EndScene(device);
438         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
439     }
440
441     color = getPixelColor(device, 320, 240);
442     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
443     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
444
445     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
446     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
447     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
448     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
449     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
450     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
451     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
452     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
453     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, old_colorwrite);
454     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
455     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
456     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
457     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
458     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
459 }
460
461 static void clear_test(IDirect3DDevice9 *device)
462 {
463     /* Tests the correctness of clearing parameters */
464     HRESULT hr;
465     D3DRECT rect[2];
466     D3DRECT rect_negneg;
467     DWORD color;
468     D3DVIEWPORT9 old_vp, vp;
469     RECT scissor;
470     DWORD oldColorWrite;
471     BOOL invalid_clear_failed = FALSE;
472
473     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
474     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
475
476     /* Positive x, negative y */
477     rect[0].x1 = 0;
478     rect[0].y1 = 480;
479     rect[0].x2 = 320;
480     rect[0].y2 = 240;
481
482     /* Positive x, positive y */
483     rect[1].x1 = 0;
484     rect[1].y1 = 0;
485     rect[1].x2 = 320;
486     rect[1].y2 = 240;
487     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
488      * returns D3D_OK, but ignores the rectangle silently
489      */
490     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
491     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
492     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
493
494     /* negative x, negative y */
495     rect_negneg.x1 = 640;
496     rect_negneg.y1 = 240;
497     rect_negneg.x2 = 320;
498     rect_negneg.y2 = 0;
499     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
500     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
501     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
502
503     color = getPixelColor(device, 160, 360); /* lower left quad */
504     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
505     color = getPixelColor(device, 160, 120); /* upper left quad */
506     if(invalid_clear_failed) {
507         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
508         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
509     } else {
510         /* If the negative rectangle was dropped silently, the correct ones are cleared */
511         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
512     }
513     color = getPixelColor(device, 480, 360); /* lower right quad  */
514     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
515     color = getPixelColor(device, 480, 120); /* upper right quad */
516     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
517
518     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
519
520     /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
521      * clear the red quad in the top left part of the render target. For some reason it
522      * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
523      * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
524      * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
525      * pick some obvious value
526      */
527     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
528     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
529
530     /* Test how the viewport affects clears */
531     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
532     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
533     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
534     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
535
536     vp.X = 160;
537     vp.Y = 120;
538     vp.Width = 160;
539     vp.Height = 120;
540     vp.MinZ = 0.0;
541     vp.MaxZ = 1.0;
542     hr = IDirect3DDevice9_SetViewport(device, &vp);
543     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
544     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
545     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
546
547     vp.X = 320;
548     vp.Y = 240;
549     vp.Width = 320;
550     vp.Height = 240;
551     vp.MinZ = 0.0;
552     vp.MaxZ = 1.0;
553     hr = IDirect3DDevice9_SetViewport(device, &vp);
554     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
555     rect[0].x1 = 160;
556     rect[0].y1 = 120;
557     rect[0].x2 = 480;
558     rect[0].y2 = 360;
559     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
560     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
561
562     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
563     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
564
565     color = getPixelColor(device, 158, 118);
566     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
567     color = getPixelColor(device, 162, 118);
568     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
569     color = getPixelColor(device, 158, 122);
570     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
571     color = getPixelColor(device, 162, 122);
572     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
573
574     color = getPixelColor(device, 318, 238);
575     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
576     color = getPixelColor(device, 322, 238);
577     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
578     color = getPixelColor(device, 318, 242);
579     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
580     color = getPixelColor(device, 322, 242);
581     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
582
583     color = getPixelColor(device, 478, 358);
584     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
585     color = getPixelColor(device, 482, 358);
586     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
587     color = getPixelColor(device, 478, 362);
588     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
589     color = getPixelColor(device, 482, 362);
590     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
591
592     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
593
594     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
595     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
596
597     scissor.left = 160;
598     scissor.right = 480;
599     scissor.top = 120;
600     scissor.bottom = 360;
601     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
602     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
603     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
604     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
605
606     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
607     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
608     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
609     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
610
611     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
612     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
613
614     color = getPixelColor(device, 158, 118);
615     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
616     color = getPixelColor(device, 162, 118);
617     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
618     color = getPixelColor(device, 158, 122);
619     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
620     color = getPixelColor(device, 162, 122);
621     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
622
623     color = getPixelColor(device, 158, 358);
624     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
625     color = getPixelColor(device, 162, 358);
626     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
627     color = getPixelColor(device, 158, 358);
628     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
629     color = getPixelColor(device, 162, 362);
630     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
631
632     color = getPixelColor(device, 478, 118);
633     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
634     color = getPixelColor(device, 478, 122);
635     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
636     color = getPixelColor(device, 482, 122);
637     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
638     color = getPixelColor(device, 482, 358);
639     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
640
641     color = getPixelColor(device, 478, 358);
642     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
643     color = getPixelColor(device, 478, 362);
644     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
645     color = getPixelColor(device, 482, 358);
646     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
647     color = getPixelColor(device, 482, 362);
648     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
649
650     color = getPixelColor(device, 318, 238);
651     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
652     color = getPixelColor(device, 318, 242);
653     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
654     color = getPixelColor(device, 322, 238);
655     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
656     color = getPixelColor(device, 322, 242);
657     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
658
659     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
660
661     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
662     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
663     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
664     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
665
666     /* Same nvidia windows driver trouble with white clears as earlier in the same test */
667     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
668     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
669
670     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
671     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
672
673     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
674     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
675
676     /* Colorwriteenable does not affect the clear */
677     color = getPixelColor(device, 320, 240);
678     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
679
680     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
681 }
682
683 static void color_fill_test(IDirect3DDevice9 *device)
684 {
685     HRESULT hr;
686     IDirect3DSurface9 *backbuffer = NULL;
687     IDirect3DSurface9 *rt_surface = NULL;
688     IDirect3DSurface9 *offscreen_surface = NULL;
689     DWORD fill_color, color;
690
691     /* Test ColorFill on a the backbuffer (should pass) */
692     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
693     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
694     if(backbuffer)
695     {
696         fill_color = 0x112233;
697         hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
698         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
699
700         color = getPixelColor(device, 0, 0);
701         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
702
703         IDirect3DSurface9_Release(backbuffer);
704     }
705
706     /* Test ColorFill on a render target surface (should pass) */
707     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
708     ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
709     if(rt_surface)
710     {
711         fill_color = 0x445566;
712         hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
713         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
714
715         color = getPixelColorFromSurface(rt_surface, 0, 0);
716         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
717
718         IDirect3DSurface9_Release(rt_surface);
719     }
720
721     /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
722     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
723             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
724     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
725     if(offscreen_surface)
726     {
727         fill_color = 0x778899;
728         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
729         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
730
731         color = getPixelColorFromSurface(offscreen_surface, 0, 0);
732         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
733
734         IDirect3DSurface9_Release(offscreen_surface);
735     }
736
737     /* Try ColorFill on a offscreen surface in sysmem (should fail) */
738     offscreen_surface = NULL;
739     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
740             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
741     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
742     if(offscreen_surface)
743     {
744         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
745         ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
746
747         IDirect3DSurface9_Release(offscreen_surface);
748     }
749 }
750
751 typedef struct {
752     float in[4];
753     DWORD out;
754 } test_data_t;
755
756 /*
757  *  c7      mova    ARGB            mov     ARGB
758  * -2.4     -2      0x00ffff00      -3      0x00ff0000
759  * -1.6     -2      0x00ffff00      -2      0x00ffff00
760  * -0.4      0      0x0000ffff      -1      0x0000ff00
761  *  0.4      0      0x0000ffff       0      0x0000ffff
762  *  1.6      2      0x00ff00ff       1      0x000000ff
763  *  2.4      2      0x00ff00ff       2      0x00ff00ff
764  */
765 static void test_mova(IDirect3DDevice9 *device)
766 {
767     static const DWORD mova_test[] = {
768         0xfffe0200,                                                             /* vs_2_0                       */
769         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
770         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
771         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
772         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
773         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
774         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
775         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
776         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
777         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
778         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
779         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
780         0x0000ffff                                                              /* END                          */
781     };
782     static const DWORD mov_test[] = {
783         0xfffe0101,                                                             /* vs_1_1                       */
784         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
785         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
786         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
787         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
788         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
789         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
790         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
791         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
792         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
793         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
794         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
795         0x0000ffff                                                              /* END                          */
796     };
797
798     static const test_data_t test_data[2][6] = {
799         {
800             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
801             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
802             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
803             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
804             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
805             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
806         },
807         {
808             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
809             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
810             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
811             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
812             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
813             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
814         }
815     };
816
817     static const float quad[][3] = {
818         {-1.0f, -1.0f, 0.0f},
819         {-1.0f,  1.0f, 0.0f},
820         { 1.0f, -1.0f, 0.0f},
821         { 1.0f,  1.0f, 0.0f},
822     };
823
824     static const D3DVERTEXELEMENT9 decl_elements[] = {
825         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
826         D3DDECL_END()
827     };
828
829     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
830     IDirect3DVertexShader9 *mova_shader = NULL;
831     IDirect3DVertexShader9 *mov_shader = NULL;
832     HRESULT hr;
833     UINT i, j;
834
835     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
836     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
837     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
838     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
839     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
840     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
841     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
842     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
843
844     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
845     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
846     for(j = 0; j < 2; ++j)
847     {
848         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
849         {
850             DWORD color;
851
852             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
853             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
854
855             hr = IDirect3DDevice9_BeginScene(device);
856             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
857
858             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
859             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
860
861             hr = IDirect3DDevice9_EndScene(device);
862             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
863
864             color = getPixelColor(device, 320, 240);
865             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
866                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
867
868             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
869             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
870
871             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
872             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
873         }
874         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
875         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
876     }
877
878     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
879     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
880
881     IDirect3DVertexDeclaration9_Release(vertex_declaration);
882     IDirect3DVertexShader9_Release(mova_shader);
883     IDirect3DVertexShader9_Release(mov_shader);
884 }
885
886 struct sVertex {
887     float x, y, z;
888     DWORD diffuse;
889     DWORD specular;
890 };
891
892 struct sVertexT {
893     float x, y, z, rhw;
894     DWORD diffuse;
895     DWORD specular;
896 };
897
898 static void fog_test(IDirect3DDevice9 *device)
899 {
900     HRESULT hr;
901     D3DCOLOR color;
902     float start = 0.0f, end = 1.0f;
903     D3DCAPS9 caps;
904     int i;
905
906     /* Gets full z based fog with linear fog, no fog with specular color */
907     struct sVertex untransformed_1[] = {
908         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
909         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
910         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
911         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
912     };
913     /* Ok, I am too lazy to deal with transform matrices */
914     struct sVertex untransformed_2[] = {
915         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
916         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
917         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
918         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
919     };
920     /* Untransformed ones. Give them a different diffuse color to make the test look
921      * nicer. It also makes making sure that they are drawn correctly easier.
922      */
923     struct sVertexT transformed_1[] = {
924         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
925         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
926         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
927         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
928     };
929     struct sVertexT transformed_2[] = {
930         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
931         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
932         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
933         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
934     };
935     struct vertex rev_fog_quads[] = {
936        {-1.0,   -1.0,   0.1,    0x000000ff},
937        {-1.0,    0.0,   0.1,    0x000000ff},
938        { 0.0,    0.0,   0.1,    0x000000ff},
939        { 0.0,   -1.0,   0.1,    0x000000ff},
940
941        { 0.0,   -1.0,   0.9,    0x000000ff},
942        { 0.0,    0.0,   0.9,    0x000000ff},
943        { 1.0,    0.0,   0.9,    0x000000ff},
944        { 1.0,   -1.0,   0.9,    0x000000ff},
945
946        { 0.0,    0.0,   0.4,    0x000000ff},
947        { 0.0,    1.0,   0.4,    0x000000ff},
948        { 1.0,    1.0,   0.4,    0x000000ff},
949        { 1.0,    0.0,   0.4,    0x000000ff},
950
951        {-1.0,    0.0,   0.7,    0x000000ff},
952        {-1.0,    1.0,   0.7,    0x000000ff},
953        { 0.0,    1.0,   0.7,    0x000000ff},
954        { 0.0,    0.0,   0.7,    0x000000ff},
955     };
956     WORD Indices[] = {0, 1, 2, 2, 3, 0};
957
958     const float ident_mat[16] =
959     {
960         1.0f, 0.0f, 0.0f, 0.0f,
961         0.0f, 1.0f, 0.0f, 0.0f,
962         0.0f, 0.0f, 1.0f, 0.0f,
963         0.0f, 0.0f, 0.0f, 1.0f
964     };
965     const float world_mat1[16] =
966     {
967         1.0f, 0.0f,  0.0f, 0.0f,
968         0.0f, 1.0f,  0.0f, 0.0f,
969         0.0f, 0.0f,  1.0f, 0.0f,
970         0.0f, 0.0f, -0.5f, 1.0f
971     };
972     const float world_mat2[16] =
973     {
974         1.0f, 0.0f, 0.0f, 0.0f,
975         0.0f, 1.0f, 0.0f, 0.0f,
976         0.0f, 0.0f, 1.0f, 0.0f,
977         0.0f, 0.0f, 1.0f, 1.0f
978     };
979     const float proj_mat[16] =
980     {
981         1.0f, 0.0f,  0.0f, 0.0f,
982         0.0f, 1.0f,  0.0f, 0.0f,
983         0.0f, 0.0f,  1.0f, 0.0f,
984         0.0f, 0.0f, -1.0f, 1.0f
985     };
986
987     const struct sVertex far_quad1[] =
988     {
989         {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
990         {-1.0f,  0.0f, 0.5f, 0xffff0000, 0xff000000},
991         { 0.0f,  0.0f, 0.5f, 0xffff0000, 0xff000000},
992         { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
993     };
994     const struct sVertex far_quad2[] =
995     {
996         {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
997         {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
998         { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
999         { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1000     };
1001
1002     memset(&caps, 0, sizeof(caps));
1003     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1004     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
1005     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1006     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1007
1008     /* Setup initial states: No lighting, fog on, fog color */
1009     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1010     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1011     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1012     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1013     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1014     ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1015
1016     /* First test: Both table fog and vertex fog off */
1017     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1018     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1019     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1020     ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1021
1022     /* Start = 0, end = 1. Should be default, but set them */
1023     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1024     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1025     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1026     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1027
1028     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1029     {
1030         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1031         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1032         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
1033         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1034                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1035                                                      sizeof(untransformed_1[0]));
1036         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1037
1038         /* That makes it use the Z value */
1039         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1040         ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
1041         /* Untransformed, vertex fog != none (or table fog != none):
1042          * Use the Z value as input into the equation
1043          */
1044         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1045                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1046                                                      sizeof(untransformed_2[0]));
1047         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1048
1049         /* transformed verts */
1050         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1051         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1052         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1053         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1054                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1055                                                      sizeof(transformed_1[0]));
1056         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1057
1058         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1059         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1060         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
1061          * equation
1062          */
1063         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1064                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
1065                                                      sizeof(transformed_2[0]));
1066         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1067
1068         hr = IDirect3DDevice9_EndScene(device);
1069         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1070     }
1071     else
1072     {
1073         ok(FALSE, "BeginScene failed\n");
1074     }
1075
1076     color = getPixelColor(device, 160, 360);
1077     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1078     color = getPixelColor(device, 160, 120);
1079     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1080     color = getPixelColor(device, 480, 120);
1081     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1082     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1083     {
1084         color = getPixelColor(device, 480, 360);
1085         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1086     }
1087     else
1088     {
1089         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1090          * The settings above result in no fogging with vertex fog
1091          */
1092         color = getPixelColor(device, 480, 120);
1093         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1094         trace("Info: Table fog not supported by this device\n");
1095     }
1096     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1097
1098     /* Now test the special case fogstart == fogend */
1099     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1100     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1101
1102     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1103     {
1104         start = 512;
1105         end = 512;
1106         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1107         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1108         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1109         ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1110
1111         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1112         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1113         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1114         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1115         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1116         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1117
1118         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1119          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1120          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1121          * The third transformed quad remains unfogged because the fogcoords are read from the specular
1122          * color and has fixed fogstart and fogend.
1123          */
1124         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1125                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1126                 sizeof(untransformed_1[0]));
1127         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1128         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1129                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1130                 sizeof(untransformed_2[0]));
1131         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1132
1133         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1134         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1135         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1136         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1137                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1138                 sizeof(transformed_1[0]));
1139         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1140
1141         hr = IDirect3DDevice9_EndScene(device);
1142         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1143     }
1144     else
1145     {
1146         ok(FALSE, "BeginScene failed\n");
1147     }
1148     color = getPixelColor(device, 160, 360);
1149     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1150     color = getPixelColor(device, 160, 120);
1151     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1152     color = getPixelColor(device, 480, 120);
1153     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1154     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1155
1156     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1157      * but without shaders it seems to work everywhere
1158      */
1159     end = 0.2;
1160     start = 0.8;
1161     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1162     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1163     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1164     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1165     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1166     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1167
1168     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1169      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1170      * so skip this for now
1171      */
1172     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1173         const char *mode = (i ? "table" : "vertex");
1174         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1175         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1176         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1177         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1178         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1179         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1180         hr = IDirect3DDevice9_BeginScene(device);
1181         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1182         if(SUCCEEDED(hr)) {
1183             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1184                                 4,  5,  6,  6,  7, 4,
1185                                 8,  9, 10, 10, 11, 8,
1186                             12, 13, 14, 14, 15, 12};
1187
1188             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1189                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1190                     sizeof(rev_fog_quads[0]));
1191             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1192
1193             hr = IDirect3DDevice9_EndScene(device);
1194             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1195         }
1196         color = getPixelColor(device, 160, 360);
1197         ok(color_match(color, 0x0000ff00, 1),
1198                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1199
1200         color = getPixelColor(device, 160, 120);
1201         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1202                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1203
1204         color = getPixelColor(device, 480, 120);
1205         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1206                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1207
1208         color = getPixelColor(device, 480, 360);
1209         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1210
1211         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1212
1213         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1214             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1215             break;
1216         }
1217     }
1218
1219     if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1220     {
1221         /* A simple fog + non-identity world matrix test */
1222         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat1);
1223         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
1224
1225         start = 0.0;
1226         end = 1.0;
1227         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1228         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1229         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1230         ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1231         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1232         ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1233         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1234         ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1235
1236         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1237         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
1238
1239         if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1240         {
1241             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1242             ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1243
1244             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1245                     2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1246             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1247
1248             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1249                     2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1250             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1251
1252             hr = IDirect3DDevice9_EndScene(device);
1253             ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1254         }
1255         else
1256         {
1257             ok(FALSE, "BeginScene failed\n");
1258         }
1259
1260         color = getPixelColor(device, 160, 360);
1261         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
1262                 "Unfogged quad has color %08x\n", color);
1263         color = getPixelColor(device, 160, 120);
1264         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1265                 "Fogged out quad has color %08x\n", color);
1266
1267         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1268
1269         /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
1270         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat2);
1271         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1272         hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)proj_mat);
1273         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1274
1275         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1276         ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1277
1278         if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1279         {
1280             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1281             ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1282
1283             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1284                     2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1285             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1286
1287             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1288                     2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1289             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1290
1291             hr = IDirect3DDevice9_EndScene(device);
1292             ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1293         }
1294         else
1295         {
1296             ok(FALSE, "BeginScene failed\n");
1297         }
1298
1299         color = getPixelColor(device, 160, 360);
1300         todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1301         color = getPixelColor(device, 160, 120);
1302         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1303                 "Fogged out quad has color %08x\n", color);
1304
1305         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1306
1307         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)ident_mat);
1308         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1309         hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)ident_mat);
1310         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1311     }
1312     else
1313     {
1314         skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1315     }
1316
1317     /* Test RANGEFOG vs FOGTABLEMODE */
1318     if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
1319             (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
1320     {
1321         struct sVertex untransformed_3[] =
1322         {
1323             {-1.0,-1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1324             {-1.0, 1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1325             { 1.0,-1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1326             { 1.0, 1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1327         };
1328
1329         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1330         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
1331         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1332         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
1333
1334         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
1335         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1336
1337         /* z=0.4999, set the fogstart to 0.5 and fogend slightly higher. If range fog
1338          * is not used, the fog coordinate will be equal to fogstart and the quad not
1339          * fogged. If range fog is used the fog coordinate will be slightly higher and
1340          * the fog coordinate will be > fogend, so we get a fully fogged quad. The fog
1341          * is calculated per vertex and interpolated, so even the center of the screen
1342          * where the difference doesn't matter will be fogged, but check the corners in
1343          * case a d3d/gl implementation decides to calculate the fog factor per fragment */
1344         start = 0.5f;
1345         end = 0.50001f;
1346         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1347         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1348         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1349         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1350
1351         /* Table fog: Range fog is not used */
1352         hr = IDirect3DDevice9_BeginScene(device);
1353         ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
1354         if (SUCCEEDED(hr))
1355         {
1356             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1357             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1358             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1359             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1360             hr = IDirect3DDevice9_EndScene(device);
1361             ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1362         }
1363         color = getPixelColor(device, 10, 10);
1364         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1365         color = getPixelColor(device, 630, 10);
1366         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1367         color = getPixelColor(device, 10, 470);
1368         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1369         color = getPixelColor(device, 630, 470);
1370         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1371
1372         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1373         ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1374
1375         /* Vertex fog: Rangefog is used */
1376         hr = IDirect3DDevice9_BeginScene(device);
1377         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP returned %#08x\n", hr);
1378         if (SUCCEEDED(hr))
1379         {
1380             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1381             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1382             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1383             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1384             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1385             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1386             hr = IDirect3DDevice9_EndScene(device);
1387             ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1388         }
1389         color = getPixelColor(device, 10, 10);
1390         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1391                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1392         color = getPixelColor(device, 630, 10);
1393         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1394                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1395         color = getPixelColor(device, 10, 470);
1396         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1397                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1398         color = getPixelColor(device, 630, 470);
1399         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1400                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1401
1402         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1403         ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1404
1405         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
1406         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1407     }
1408     else
1409     {
1410         skip("Range fog or table fog not supported, skipping range fog tests\n");
1411     }
1412
1413     /* Turn off the fog master switch to avoid confusing other tests */
1414     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1415     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1416     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1417     ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1418     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1419     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1420 }
1421
1422 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1423  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1424  * regardless of the actual addressing mode set. The way this test works is
1425  * that we sample in one of the corners of the cubemap with filtering enabled,
1426  * and check the interpolated color. There are essentially two reasonable
1427  * things an implementation can do: Either pick one of the faces and
1428  * interpolate the edge texel with itself (i.e., clamp within the face), or
1429  * interpolate between the edge texels of the three involved faces. It should
1430  * never involve the border color or the other side (texcoord wrapping) of a
1431  * face in the interpolation. */
1432 static void test_cube_wrap(IDirect3DDevice9 *device)
1433 {
1434     static const float quad[][6] = {
1435         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1436         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1437         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1438         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1439     };
1440
1441     static const D3DVERTEXELEMENT9 decl_elements[] = {
1442         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1443         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1444         D3DDECL_END()
1445     };
1446
1447     static const struct {
1448         D3DTEXTUREADDRESS mode;
1449         const char *name;
1450     } address_modes[] = {
1451         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1452         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1453         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1454         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1455         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1456     };
1457
1458     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1459     IDirect3DCubeTexture9 *texture = NULL;
1460     IDirect3DSurface9 *surface = NULL;
1461     IDirect3DSurface9 *face_surface;
1462     D3DLOCKED_RECT locked_rect;
1463     HRESULT hr;
1464     UINT x;
1465     INT y, face;
1466
1467     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1468     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1469     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1470     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1471
1472     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1473             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1474     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1475
1476     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1477             D3DPOOL_DEFAULT, &texture, NULL);
1478     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1479
1480     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1481     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1482
1483     for (y = 0; y < 128; ++y)
1484     {
1485         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1486         for (x = 0; x < 64; ++x)
1487         {
1488             *ptr++ = 0xff0000ff;
1489         }
1490         for (x = 64; x < 128; ++x)
1491         {
1492             *ptr++ = 0xffff0000;
1493         }
1494     }
1495
1496     hr = IDirect3DSurface9_UnlockRect(surface);
1497     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1498
1499     hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1500     ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1501
1502     hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1503     ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1504
1505     IDirect3DSurface9_Release(face_surface);
1506
1507     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1508     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1509
1510     for (y = 0; y < 128; ++y)
1511     {
1512         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1513         for (x = 0; x < 64; ++x)
1514         {
1515             *ptr++ = 0xffff0000;
1516         }
1517         for (x = 64; x < 128; ++x)
1518         {
1519             *ptr++ = 0xff0000ff;
1520         }
1521     }
1522
1523     hr = IDirect3DSurface9_UnlockRect(surface);
1524     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1525
1526     /* Create cube faces */
1527     for (face = 1; face < 6; ++face)
1528     {
1529         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1530         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1531
1532         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1533         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1534
1535         IDirect3DSurface9_Release(face_surface);
1536     }
1537
1538     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1539     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1540
1541     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1542     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1543     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1544     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1545     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1546     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1547
1548     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1549     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1550
1551     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1552     {
1553         DWORD color;
1554
1555         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1556         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1557         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1558         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1559
1560         hr = IDirect3DDevice9_BeginScene(device);
1561         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1562
1563         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1564         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1565
1566         hr = IDirect3DDevice9_EndScene(device);
1567         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1568
1569         color = getPixelColor(device, 320, 240);
1570         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1571                 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1572                 color, address_modes[x].name);
1573
1574         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1575         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1576
1577         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1578         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1579     }
1580
1581     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1582     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1583
1584     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1585     IDirect3DCubeTexture9_Release(texture);
1586     IDirect3DSurface9_Release(surface);
1587 }
1588
1589 static void offscreen_test(IDirect3DDevice9 *device)
1590 {
1591     HRESULT hr;
1592     IDirect3DTexture9 *offscreenTexture = NULL;
1593     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1594     DWORD color;
1595
1596     static const float quad[][5] = {
1597         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1598         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1599         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1600         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1601     };
1602
1603     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1604     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1605
1606     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1607     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1608     if(!offscreenTexture) {
1609         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1610         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1611         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1612         if(!offscreenTexture) {
1613             skip("Cannot create an offscreen render target\n");
1614             goto out;
1615         }
1616     }
1617
1618     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1619     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1620     if(!backbuffer) {
1621         goto out;
1622     }
1623
1624     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1625     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1626     if(!offscreen) {
1627         goto out;
1628     }
1629
1630     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1631     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1632
1633     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1634     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1635     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1636     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1637     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1638     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1639     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1640     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1641     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1642     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1643
1644     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1645         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1646         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1647         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1648         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1649
1650         /* Draw without textures - Should result in a white quad */
1651         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1652         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1653
1654         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1655         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1656         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1657         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1658
1659         /* This time with the texture */
1660         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1661         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1662
1663         IDirect3DDevice9_EndScene(device);
1664     }
1665
1666     /* Center quad - should be white */
1667     color = getPixelColor(device, 320, 240);
1668     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1669     /* Some quad in the cleared part of the texture */
1670     color = getPixelColor(device, 170, 240);
1671     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1672     /* Part of the originally cleared back buffer */
1673     color = getPixelColor(device, 10, 10);
1674     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1675     if(0) {
1676         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1677          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1678          * the offscreen rendering mode this test would succeed or fail
1679          */
1680         color = getPixelColor(device, 10, 470);
1681         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1682     }
1683
1684     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1685
1686 out:
1687     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1688     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1689
1690     /* restore things */
1691     if(backbuffer) {
1692         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1693         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1694         IDirect3DSurface9_Release(backbuffer);
1695     }
1696     if(offscreenTexture) {
1697         IDirect3DTexture9_Release(offscreenTexture);
1698     }
1699     if(offscreen) {
1700         IDirect3DSurface9_Release(offscreen);
1701     }
1702 }
1703
1704 /* This test tests fog in combination with shaders.
1705  * What's tested: linear fog (vertex and table) with pixel shader
1706  *                linear table fog with non foggy vertex shader
1707  *                vertex fog with foggy vertex shader, non-linear
1708  *                fog with shader, non-linear fog with foggy shader,
1709  *                linear table fog with foggy shader
1710  */
1711 static void fog_with_shader_test(IDirect3DDevice9 *device)
1712 {
1713     HRESULT hr;
1714     DWORD color;
1715     union {
1716         float f;
1717         DWORD i;
1718     } start, end;
1719     unsigned int i, j;
1720
1721     /* basic vertex shader without fog computation ("non foggy") */
1722     static const DWORD vertex_shader_code1[] = {
1723         0xfffe0101,                                                             /* vs_1_1                       */
1724         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1725         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1726         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1727         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1728         0x0000ffff
1729     };
1730     /* basic vertex shader with reversed fog computation ("foggy") */
1731     static const DWORD vertex_shader_code2[] = {
1732         0xfffe0101,                                                             /* vs_1_1                        */
1733         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1734         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1735         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1736         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1737         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1738         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1739         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1740         0x0000ffff
1741     };
1742     /* basic pixel shader */
1743     static const DWORD pixel_shader_code[] = {
1744         0xffff0101,                                                             /* ps_1_1     */
1745         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1746         0x0000ffff
1747     };
1748
1749     static struct vertex quad[] = {
1750         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1751         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1752         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1753         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1754     };
1755
1756     static const D3DVERTEXELEMENT9 decl_elements[] = {
1757         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1758         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1759         D3DDECL_END()
1760     };
1761
1762     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1763     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1764     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1765
1766     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1767     static const struct test_data_t {
1768         int vshader;
1769         int pshader;
1770         D3DFOGMODE vfog;
1771         D3DFOGMODE tfog;
1772         unsigned int color[11];
1773     } test_data[] = {
1774         /* only pixel shader: */
1775         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1776         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1777         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1778         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1779         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1780         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1781         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1782         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1783         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1784         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1785         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1786         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1787         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1788         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1789         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1790
1791         /* vertex shader */
1792         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1793         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1794          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1795         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1796         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1797         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1798         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1799         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1800         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1801
1802         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1803         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1804         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1805         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1806         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1807         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1808
1809         /* vertex shader and pixel shader */
1810         /* The next 4 tests would read the fog coord output, but it isn't available.
1811          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1812          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1813          * These tests should be disabled if some other hardware behaves differently
1814          */
1815         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1816         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1817         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1818         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1819         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1820         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1821         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1822         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1823         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1824         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1825         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1826         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1827
1828         /* These use the Z coordinate with linear table fog */
1829         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1830         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1831         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1832         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1833         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1834         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1835         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1836         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1837         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1838         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1839         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1840         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1841
1842         /* Non-linear table fog without fog coord */
1843         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1844         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1845         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1846         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1847         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1848         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1849
1850 #if 0  /* FIXME: these fail on GeForce 8500 */
1851         /* foggy vertex shader */
1852         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1853         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1854          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1855         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1856         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1857          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1858         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1859         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1860          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1861         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1862         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1863          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1864 #endif
1865
1866         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1867          * all using the fixed fog-coord linear fog
1868          */
1869         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1870         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1871          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1872         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1873         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1874          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1875         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1876         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1877          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1878         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1879         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1880          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1881
1882         /* These use table fog. Here the shader-provided fog coordinate is
1883          * ignored and the z coordinate used instead
1884          */
1885         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1886         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1887         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1888         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1889         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1890         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1891         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1892         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1893         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1894     };
1895
1896     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1897     start.f=0.1f;
1898     end.f=0.9f;
1899
1900     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1901     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1902     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1903     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1904     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1905     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1906     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1907     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1908
1909     /* Setup initial states: No lighting, fog on, fog color */
1910     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1911     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1912     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1913     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1914     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1915     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1916     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1917     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1918
1919     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1920     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1921     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1922     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1923
1924     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1925     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1926     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1927     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1928     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1929
1930     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1931     {
1932         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1933         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1934         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1935         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1936         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1937         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1938         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1939         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1940
1941         for(j=0; j < 11; j++)
1942         {
1943             /* Don't use the whole zrange to prevent rounding errors */
1944             quad[0].z = 0.001f + (float)j / 10.02f;
1945             quad[1].z = 0.001f + (float)j / 10.02f;
1946             quad[2].z = 0.001f + (float)j / 10.02f;
1947             quad[3].z = 0.001f + (float)j / 10.02f;
1948
1949             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1950             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1951
1952             hr = IDirect3DDevice9_BeginScene(device);
1953             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1954
1955             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1956             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1957
1958             hr = IDirect3DDevice9_EndScene(device);
1959             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1960
1961             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1962             color = getPixelColor(device, 128, 240);
1963             ok(color_match(color, test_data[i].color[j], 13),
1964                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1965                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1966
1967             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1968         }
1969     }
1970
1971     /* reset states */
1972     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1973     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1974     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1975     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1976     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1977     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1978     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1979     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1980
1981     IDirect3DVertexShader9_Release(vertex_shader[1]);
1982     IDirect3DVertexShader9_Release(vertex_shader[2]);
1983     IDirect3DPixelShader9_Release(pixel_shader[1]);
1984     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1985 }
1986
1987 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1988     unsigned int i, x, y;
1989     HRESULT hr;
1990     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1991     D3DLOCKED_RECT locked_rect;
1992
1993     /* Generate the textures */
1994     for(i=0; i<2; i++)
1995     {
1996         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1997                                             D3DPOOL_MANAGED, &texture[i], NULL);
1998         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1999
2000         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
2001         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2002         for (y = 0; y < 128; ++y)
2003         {
2004             if(i)
2005             { /* Set up black texture with 2x2 texel white spot in the middle */
2006                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2007                 for (x = 0; x < 128; ++x)
2008                 {
2009                     if(y>62 && y<66 && x>62 && x<66)
2010                         *ptr++ = 0xffffffff;
2011                     else
2012                         *ptr++ = 0xff000000;
2013                 }
2014             }
2015             else
2016             { /* Set up a displacement map which points away from the center parallel to the closest axis.
2017                * (if multiplied with bumpenvmat)
2018               */
2019                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2020                 for (x = 0; x < 128; ++x)
2021                 {
2022                     if(abs(x-64)>abs(y-64))
2023                     {
2024                         if(x < 64)
2025                             *ptr++ = 0xc000;
2026                         else
2027                             *ptr++ = 0x4000;
2028                     }
2029                     else
2030                     {
2031                         if(y < 64)
2032                             *ptr++ = 0x0040;
2033                         else
2034                             *ptr++ = 0x00c0;
2035                     }
2036                 }
2037             }
2038         }
2039         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2040         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2041
2042         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2043         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2044
2045         /* Disable texture filtering */
2046         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2047         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2048         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2049         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2050
2051         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2052         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2053         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2054         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2055     }
2056 }
2057
2058 /* test the behavior of the texbem instruction
2059  * with normal 2D and projective 2D textures
2060  */
2061 static void texbem_test(IDirect3DDevice9 *device)
2062 {
2063     HRESULT hr;
2064     DWORD color;
2065     int i;
2066
2067     static const DWORD pixel_shader_code[] = {
2068         0xffff0101,                         /* ps_1_1*/
2069         0x00000042, 0xb00f0000,             /* tex t0*/
2070         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2071         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
2072         0x0000ffff
2073     };
2074     static const DWORD double_texbem_code[] =  {
2075         0xffff0103,                                         /* ps_1_3           */
2076         0x00000042, 0xb00f0000,                             /* tex t0           */
2077         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
2078         0x00000042, 0xb00f0002,                             /* tex t2           */
2079         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
2080         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
2081         0x0000ffff                                          /* end              */
2082     };
2083
2084
2085     static const float quad[][7] = {
2086         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
2087         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
2088         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
2089         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
2090     };
2091     static const float quad_proj[][9] = {
2092         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
2093         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
2094         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
2095         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
2096     };
2097
2098     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
2099         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2100         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2101         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2102         D3DDECL_END()
2103     },{
2104         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2105         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2106         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2107         D3DDECL_END()
2108     } };
2109
2110     /* use asymmetric matrix to test loading */
2111     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
2112
2113     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2114     IDirect3DPixelShader9       *pixel_shader       = NULL;
2115     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
2116     D3DLOCKED_RECT locked_rect;
2117
2118     generate_bumpmap_textures(device);
2119
2120     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2121     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2122     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2123     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2124     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
2125
2126     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2127     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2128
2129     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2130     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2131
2132     for(i=0; i<2; i++)
2133     {
2134         if(i)
2135         {
2136             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
2137             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2138         }
2139
2140         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
2141         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2142         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2143         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2144
2145         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
2146         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2147         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2148         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2149
2150         hr = IDirect3DDevice9_BeginScene(device);
2151         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2152
2153         if(!i)
2154             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2155         else
2156             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
2157         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2158
2159         hr = IDirect3DDevice9_EndScene(device);
2160         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2161
2162         color = getPixelColor(device, 320-32, 240);
2163         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2164         color = getPixelColor(device, 320+32, 240);
2165         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2166         color = getPixelColor(device, 320, 240-32);
2167         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2168         color = getPixelColor(device, 320, 240+32);
2169         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2170
2171         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2172         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2173
2174         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2175         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2176         IDirect3DPixelShader9_Release(pixel_shader);
2177
2178         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2179         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2180         IDirect3DVertexDeclaration9_Release(vertex_declaration);
2181     }
2182
2183     /* clean up */
2184     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2185     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2186
2187     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2188     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2189
2190     for(i=0; i<2; i++)
2191     {
2192         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
2193         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
2194         IDirect3DTexture9_Release(texture); /* For the GetTexture */
2195         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2196         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2197         IDirect3DTexture9_Release(texture);
2198     }
2199
2200     /* Test double texbem */
2201     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
2202     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2203     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
2204     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2205     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
2206     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2207     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
2208     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2209
2210     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
2211     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2212     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
2213     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
2214
2215     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2216     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2217
2218     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
2219     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2220     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
2221     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
2222     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
2223     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2224
2225     {
2226         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
2227 #define tex  0x00ff0000
2228 #define tex1 0x0000ff00
2229 #define origin 0x000000ff
2230         static const DWORD pixel_data[] = {
2231             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2232             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2233             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2234             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2235             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
2236             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2237             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2238             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2239         };
2240 #undef tex1
2241 #undef tex2
2242 #undef origin
2243
2244         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
2245         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2246         for(i = 0; i < 8; i++) {
2247             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
2248         }
2249         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
2250         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2251     }
2252
2253     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2254     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2255     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
2256     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2257     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
2258     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2259     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2260     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2261     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2262     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2263     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2264     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2265
2266     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
2267     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
2268     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2269     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2270     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2271     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2272     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2273     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2274     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2275     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2276
2277     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2278     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2279     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2280     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2281     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2282     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2283     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2284     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2285     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2286     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2287
2288     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2289     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2290     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2291     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2292     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2293     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2294     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2295     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2296     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2297     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2298     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2299     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2300     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2301     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2302     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2303     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2304
2305     hr = IDirect3DDevice9_BeginScene(device);
2306     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2307     if(SUCCEEDED(hr)) {
2308         static const float double_quad[] = {
2309             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2310              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2311             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2312              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2313         };
2314
2315         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2316         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2317         hr = IDirect3DDevice9_EndScene(device);
2318         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2319     }
2320     color = getPixelColor(device, 320, 240);
2321     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2322
2323     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2324     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2325     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2326     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2327     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2328     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2329     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2330     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2331     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2332     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2333
2334     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2335     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2336
2337     IDirect3DPixelShader9_Release(pixel_shader);
2338     IDirect3DTexture9_Release(texture);
2339     IDirect3DTexture9_Release(texture1);
2340     IDirect3DTexture9_Release(texture2);
2341 }
2342
2343 static void z_range_test(IDirect3DDevice9 *device)
2344 {
2345     const struct vertex quad[] =
2346     {
2347         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2348         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2349         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2350         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2351     };
2352     const struct vertex quad2[] =
2353     {
2354         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2355         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2356         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2357         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2358     };
2359
2360     const struct tvertex quad3[] =
2361     {
2362         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2363         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2364         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2365         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2366     };
2367     const struct tvertex quad4[] =
2368     {
2369         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2370         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2371         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2372         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2373     };
2374     HRESULT hr;
2375     DWORD color;
2376     IDirect3DVertexShader9 *shader;
2377     IDirect3DVertexDeclaration9 *decl;
2378     D3DCAPS9 caps;
2379     const DWORD shader_code[] = {
2380         0xfffe0101,                                     /* vs_1_1           */
2381         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2382         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2383         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2384         0x0000ffff                                      /* end              */
2385     };
2386     static const D3DVERTEXELEMENT9 decl_elements[] = {
2387         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2388         D3DDECL_END()
2389     };
2390
2391     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2392
2393     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2394      * then call Present. Then clear the color buffer to make sure it has some defined content
2395      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2396      * by the depth value.
2397      */
2398     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2399     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2400     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2401     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2402     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2403     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2404
2405     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2406     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2407     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2408     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2409     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2410     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2411     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2412     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2413     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2414     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2415
2416     hr = IDirect3DDevice9_BeginScene(device);
2417     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2418     if(hr == D3D_OK)
2419     {
2420         /* Test the untransformed vertex path */
2421         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2422         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2423         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2424         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2425         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2426         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2427
2428         /* Test the transformed vertex path */
2429         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2430         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2431
2432         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2433         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2434         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2435         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2436         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2437         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2438
2439         hr = IDirect3DDevice9_EndScene(device);
2440         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2441     }
2442
2443     /* Do not test the exact corner pixels, but go pretty close to them */
2444
2445     /* Clipped because z > 1.0 */
2446     color = getPixelColor(device, 28, 238);
2447     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2448     color = getPixelColor(device, 28, 241);
2449     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2450     {
2451         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2452     }
2453     else
2454     {
2455         ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2456     }
2457
2458     /* Not clipped, > z buffer clear value(0.75) */
2459     color = getPixelColor(device, 31, 238);
2460     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2461     color = getPixelColor(device, 31, 241);
2462     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2463     color = getPixelColor(device, 100, 238);
2464     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2465     color = getPixelColor(device, 100, 241);
2466     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2467
2468     /* Not clipped, < z buffer clear value */
2469     color = getPixelColor(device, 104, 238);
2470     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2471     color = getPixelColor(device, 104, 241);
2472     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2473     color = getPixelColor(device, 318, 238);
2474     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2475     color = getPixelColor(device, 318, 241);
2476     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2477
2478     /* Clipped because z < 0.0 */
2479     color = getPixelColor(device, 321, 238);
2480     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2481     color = getPixelColor(device, 321, 241);
2482     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2483     {
2484         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2485     }
2486     else
2487     {
2488         ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2489     }
2490
2491     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2492     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2493
2494     /* Test the shader path */
2495     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2496         skip("Vertex shaders not supported\n");
2497         goto out;
2498     }
2499     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2500     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2501     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2502     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2503
2504     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2505
2506     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2507     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2508     IDirect3DDevice9_SetVertexShader(device, shader);
2509     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2510
2511     hr = IDirect3DDevice9_BeginScene(device);
2512     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2513     if(hr == D3D_OK)
2514     {
2515         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2516         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2517         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2518         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2519         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2520         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2521         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2522         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2523         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2524         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2525
2526         hr = IDirect3DDevice9_EndScene(device);
2527         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2528     }
2529
2530     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2531     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2532     IDirect3DDevice9_SetVertexShader(device, NULL);
2533     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2534
2535     IDirect3DVertexDeclaration9_Release(decl);
2536     IDirect3DVertexShader9_Release(shader);
2537
2538     /* Z < 1.0 */
2539     color = getPixelColor(device, 28, 238);
2540     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2541
2542     /* 1.0 < z < 0.75 */
2543     color = getPixelColor(device, 31, 238);
2544     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2545     color = getPixelColor(device, 100, 238);
2546     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2547
2548     /* 0.75 < z < 0.0 */
2549     color = getPixelColor(device, 104, 238);
2550     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2551     color = getPixelColor(device, 318, 238);
2552     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2553
2554     /* 0.0 < z */
2555     color = getPixelColor(device, 321, 238);
2556     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2557
2558     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2559     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2560
2561     out:
2562     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2563     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2564     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2565     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2566     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2567     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2568 }
2569
2570 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2571 {
2572     D3DSURFACE_DESC desc;
2573     D3DLOCKED_RECT l;
2574     HRESULT hr;
2575     unsigned int x, y;
2576     DWORD *mem;
2577
2578     memset(&desc, 0, sizeof(desc));
2579     memset(&l, 0, sizeof(l));
2580     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2581     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2582     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2583     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2584     if(FAILED(hr)) return;
2585
2586     for(y = 0; y < desc.Height; y++)
2587     {
2588         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2589         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2590         {
2591             mem[x] = color;
2592         }
2593     }
2594     hr = IDirect3DSurface9_UnlockRect(surface);
2595     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2596 }
2597
2598 /* This tests a variety of possible StretchRect() situations */
2599 static void stretchrect_test(IDirect3DDevice9 *device)
2600 {
2601     HRESULT hr;
2602     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2603     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2604     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2605     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2606     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2607     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2608     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2609     IDirect3DSurface9 *orig_rt = NULL;
2610     IDirect3DSurface9 *backbuffer = NULL;
2611     DWORD color;
2612
2613     RECT src_rect64 = {0, 0, 64, 64};
2614     RECT src_rect64_flipy = {0, 64, 64, 0};
2615     RECT dst_rect64 = {0, 0, 64, 64};
2616     RECT dst_rect64_flipy = {0, 64, 64, 0};
2617
2618     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2619     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2620     if(!orig_rt) {
2621         goto out;
2622     }
2623
2624     /* Create our temporary surfaces in system memory */
2625     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2626     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2627     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2628     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2629
2630     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2631     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2632     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2633     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2634     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2635     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2636     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2637
2638     /* Create render target surfaces */
2639     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2640     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2641     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2642     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2643     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2644     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2645     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2646     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2647
2648     /* Create render target textures */
2649     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2650     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2651     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2652     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2653     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2654     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2655     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2656     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2657     if (tex_rt32) {
2658         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2659         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2660     }
2661     if (tex_rt64) {
2662         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2663         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2664     }
2665     if (tex_rt_dest64) {
2666         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2667         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2668     }
2669     if (tex_rt_dest64) {
2670         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2671         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2672     }
2673
2674     /* Create regular textures in D3DPOOL_DEFAULT */
2675     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2676     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2677     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2678     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2679     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2680     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2681     if (tex32) {
2682         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2683         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2684     }
2685     if (tex64) {
2686         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2687         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2688     }
2689     if (tex_dest64) {
2690         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2691         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2692     }
2693
2694     /*********************************************************************
2695      * Tests for when the source parameter is an offscreen plain surface *
2696      *********************************************************************/
2697
2698     /* Fill the offscreen 64x64 surface with green */
2699     if (surf_offscreen64)
2700         fill_surface(surf_offscreen64, 0xff00ff00);
2701
2702     /* offscreenplain ==> offscreenplain, same size */
2703     if(surf_offscreen64 && surf_offscreen_dest64) {
2704         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2705         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2706
2707         if (hr == D3D_OK) {
2708             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2709             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2710         }
2711
2712         /* Blit without scaling */
2713         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2714         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2715
2716         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2717         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2718         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2719
2720         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2721         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2722         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2723     }
2724
2725     /* offscreenplain ==> rendertarget texture, same size */
2726     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2727         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2728         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2729
2730         /* We can't lock rendertarget textures, so copy to our temp surface first */
2731         if (hr == D3D_OK) {
2732             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2733             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2734         }
2735
2736         if (hr == D3D_OK) {
2737             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2738             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2739         }
2740
2741         /* Blit without scaling */
2742         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2743         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2744
2745         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2746         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2747         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2748
2749         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2750         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2751         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2752     }
2753
2754     /* offscreenplain ==> rendertarget surface, same size */
2755     if(surf_offscreen64 && surf_rt_dest64) {
2756         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2757         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2758
2759         if (hr == D3D_OK) {
2760             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2761             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2762         }
2763
2764         /* Blit without scaling */
2765         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2766         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2767
2768         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2769         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2770         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2771
2772         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2773         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2774         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2775     }
2776
2777     /* offscreenplain ==> texture, same size (should fail) */
2778     if(surf_offscreen64 && surf_tex_dest64) {
2779         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2780         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2781     }
2782
2783     /* Fill the smaller offscreen surface with red */
2784     fill_surface(surf_offscreen32, 0xffff0000);
2785
2786     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2787     if(surf_offscreen32 && surf_offscreen64) {
2788         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2789         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2790     }
2791
2792     /* offscreenplain ==> rendertarget texture, scaling */
2793     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2794         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2795         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2796
2797         /* We can't lock rendertarget textures, so copy to our temp surface first */
2798         if (hr == D3D_OK) {
2799             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2800             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2801         }
2802
2803         if (hr == D3D_OK) {
2804             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2805             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2806         }
2807     }
2808
2809     /* offscreenplain ==> rendertarget surface, scaling */
2810     if(surf_offscreen32 && surf_rt_dest64) {
2811         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2812         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2813
2814         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2815         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2816     }
2817
2818     /* offscreenplain ==> texture, scaling (should fail) */
2819     if(surf_offscreen32 && surf_tex_dest64) {
2820         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2821         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2822     }
2823
2824     /************************************************************
2825      * Tests for when the source parameter is a regular texture *
2826      ************************************************************/
2827
2828     /* Fill the surface of the regular texture with blue */
2829     if (surf_tex64 && surf_temp64) {
2830         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2831         fill_surface(surf_temp64, 0xff0000ff);
2832         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2833         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2834     }
2835
2836     /* texture ==> offscreenplain, same size */
2837     if(surf_tex64 && surf_offscreen64) {
2838         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2839         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2840     }
2841
2842     /* texture ==> rendertarget texture, same size */
2843     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2844         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2845         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2846
2847         /* We can't lock rendertarget textures, so copy to our temp surface first */
2848         if (hr == D3D_OK) {
2849             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2850             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2851         }
2852
2853         if (hr == D3D_OK) {
2854             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2855             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2856         }
2857
2858         /* Blit without scaling */
2859         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2860         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2861
2862         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2863         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2864         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2865
2866         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2867         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2868         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2869     }
2870
2871     /* texture ==> rendertarget surface, same size */
2872     if(surf_tex64 && surf_rt_dest64) {
2873         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2874         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2875
2876         if (hr == D3D_OK) {
2877             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2878             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2879         }
2880
2881         /* Blit without scaling */
2882         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2883         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2884
2885         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2886         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2887         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2888
2889         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2890         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2891         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2892     }
2893
2894     /* texture ==> texture, same size (should fail) */
2895     if(surf_tex64 && surf_tex_dest64) {
2896         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2897         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2898     }
2899
2900     /* Fill the surface of the smaller regular texture with red */
2901     if (surf_tex32 && surf_temp32) {
2902         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2903         fill_surface(surf_temp32, 0xffff0000);
2904         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2905         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2906     }
2907
2908     /* texture ==> offscreenplain, scaling (should fail) */
2909     if(surf_tex32 && surf_offscreen64) {
2910         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2911         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2912     }
2913
2914     /* texture ==> rendertarget texture, scaling */
2915     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2916         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2917         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2918
2919         /* We can't lock rendertarget textures, so copy to our temp surface first */
2920         if (hr == D3D_OK) {
2921             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2922             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2923         }
2924
2925         if (hr == D3D_OK) {
2926             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2927             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2928         }
2929     }
2930
2931     /* texture ==> rendertarget surface, scaling */
2932     if(surf_tex32 && surf_rt_dest64) {
2933         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2934         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2935
2936         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2937         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2938     }
2939
2940     /* texture ==> texture, scaling (should fail) */
2941     if(surf_tex32 && surf_tex_dest64) {
2942         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2943         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2944     }
2945
2946     /*****************************************************************
2947      * Tests for when the source parameter is a rendertarget texture *
2948      *****************************************************************/
2949
2950     /* Fill the surface of the rendertarget texture with white */
2951     if (surf_tex_rt64 && surf_temp64) {
2952         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2953         fill_surface(surf_temp64, 0xffffffff);
2954         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2955         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2956     }
2957
2958     /* rendertarget texture ==> offscreenplain, same size */
2959     if(surf_tex_rt64 && surf_offscreen64) {
2960         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2961         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2962     }
2963
2964     /* rendertarget texture ==> rendertarget texture, same size */
2965     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2966         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2967         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2968
2969         /* We can't lock rendertarget textures, so copy to our temp surface first */
2970         if (hr == D3D_OK) {
2971             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2972             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2973         }
2974
2975         if (hr == D3D_OK) {
2976             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2977             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2978         }
2979
2980         /* Blit without scaling */
2981         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2982         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2983
2984         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2985         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2986         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2987
2988         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2989         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2990         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2991     }
2992
2993     /* rendertarget texture ==> rendertarget surface, same size */
2994     if(surf_tex_rt64 && surf_rt_dest64) {
2995         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2996         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2997
2998         if (hr == D3D_OK) {
2999             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3000             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
3001         }
3002
3003         /* Blit without scaling */
3004         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3005         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3006
3007         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3008         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
3009         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3010
3011         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3012         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3013         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3014     }
3015
3016     /* rendertarget texture ==> texture, same size (should fail) */
3017     if(surf_tex_rt64 && surf_tex_dest64) {
3018         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
3019         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3020     }
3021
3022     /* Fill the surface of the smaller rendertarget texture with red */
3023     if (surf_tex_rt32 && surf_temp32) {
3024         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
3025         fill_surface(surf_temp32, 0xffff0000);
3026         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3027         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3028     }
3029
3030     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
3031     if(surf_tex_rt32 && surf_offscreen64) {
3032         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
3033         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3034     }
3035
3036     /* rendertarget texture ==> rendertarget texture, scaling */
3037     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3038         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3039         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3040
3041         /* We can't lock rendertarget textures, so copy to our temp surface first */
3042         if (hr == D3D_OK) {
3043             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3044             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3045         }
3046
3047         if (hr == D3D_OK) {
3048             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3049             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3050         }
3051     }
3052
3053     /* rendertarget texture ==> rendertarget surface, scaling */
3054     if(surf_tex_rt32 && surf_rt_dest64) {
3055         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
3056         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3057
3058         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3059         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3060     }
3061
3062     /* rendertarget texture ==> texture, scaling (should fail) */
3063     if(surf_tex_rt32 && surf_tex_dest64) {
3064         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
3065         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3066     }
3067
3068     /*****************************************************************
3069      * Tests for when the source parameter is a rendertarget surface *
3070      *****************************************************************/
3071
3072     /* Fill the surface of the rendertarget surface with black */
3073     if (surf_rt64)
3074         fill_surface(surf_rt64, 0xff000000);
3075
3076     /* rendertarget texture ==> offscreenplain, same size */
3077     if(surf_rt64 && surf_offscreen64) {
3078         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
3079         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3080     }
3081
3082     /* rendertarget surface ==> rendertarget texture, same size */
3083     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3084         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3085         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3086
3087         /* We can't lock rendertarget textures, so copy to our temp surface first */
3088         if (hr == D3D_OK) {
3089             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3090             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3091         }
3092
3093         if (hr == D3D_OK) {
3094             color = getPixelColorFromSurface(surf_temp64, 32, 32);
3095             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3096         }
3097
3098         /* Blit without scaling */
3099         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3100         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3101
3102         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3103         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3104         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3105
3106         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3107         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3108         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3109     }
3110
3111     /* rendertarget surface ==> rendertarget surface, same size */
3112     if(surf_rt64 && surf_rt_dest64) {
3113         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
3114         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3115
3116         if (hr == D3D_OK) {
3117             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3118             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3119         }
3120
3121         /* Blit without scaling */
3122         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3123         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3124
3125         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3126         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
3127         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3128
3129         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3130         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3131         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3132     }
3133
3134     /* rendertarget surface ==> texture, same size (should fail) */
3135     if(surf_rt64 && surf_tex_dest64) {
3136         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
3137         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3138     }
3139
3140     /* Fill the surface of the smaller rendertarget texture with red */
3141     if (surf_rt32)
3142         fill_surface(surf_rt32, 0xffff0000);
3143
3144     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
3145     if(surf_rt32 && surf_offscreen64) {
3146         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
3147         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3148     }
3149
3150     /* rendertarget surface ==> rendertarget texture, scaling */
3151     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3152         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3153         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3154
3155         /* We can't lock rendertarget textures, so copy to our temp surface first */
3156         if (hr == D3D_OK) {
3157             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3158             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3159         }
3160
3161         if (hr == D3D_OK) {
3162             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3163             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3164         }
3165     }
3166
3167     /* rendertarget surface ==> rendertarget surface, scaling */
3168     if(surf_rt32 && surf_rt_dest64) {
3169         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
3170         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3171
3172         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3173         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3174     }
3175
3176     /* rendertarget surface ==> texture, scaling (should fail) */
3177     if(surf_rt32 && surf_tex_dest64) {
3178         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
3179         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3180     }
3181
3182     /* backbuffer ==> surface tests (no scaling) */
3183     if(backbuffer && surf_tex_rt_dest640_480)
3184     {
3185         RECT src_rect = {0, 0, 640, 480};
3186         RECT src_rect_flipy = {0, 480, 640, 0};
3187         RECT dst_rect = {0, 0, 640, 480};
3188         RECT dst_rect_flipy = {0, 480, 640, 0};
3189
3190         /* Blit with NULL rectangles */
3191         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
3192         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
3193
3194         /* Blit without scaling */
3195         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
3196         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3197
3198         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3199         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
3200         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3201
3202         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3203         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
3204         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3205     }
3206
3207     /* TODO: Test format conversions */
3208
3209
3210 out:
3211     /* Clean up */
3212     if (backbuffer)
3213         IDirect3DSurface9_Release(backbuffer);
3214     if (surf_rt32)
3215         IDirect3DSurface9_Release(surf_rt32);
3216     if (surf_rt64)
3217         IDirect3DSurface9_Release(surf_rt64);
3218     if (surf_rt_dest64)
3219         IDirect3DSurface9_Release(surf_rt_dest64);
3220     if (surf_temp32)
3221         IDirect3DSurface9_Release(surf_temp32);
3222     if (surf_temp64)
3223         IDirect3DSurface9_Release(surf_temp64);
3224     if (surf_offscreen32)
3225         IDirect3DSurface9_Release(surf_offscreen32);
3226     if (surf_offscreen64)
3227         IDirect3DSurface9_Release(surf_offscreen64);
3228     if (surf_offscreen_dest64)
3229         IDirect3DSurface9_Release(surf_offscreen_dest64);
3230
3231     if (tex_rt32) {
3232         if (surf_tex_rt32)
3233             IDirect3DSurface9_Release(surf_tex_rt32);
3234         IDirect3DTexture9_Release(tex_rt32);
3235     }
3236     if (tex_rt64) {
3237         if (surf_tex_rt64)
3238             IDirect3DSurface9_Release(surf_tex_rt64);
3239         IDirect3DTexture9_Release(tex_rt64);
3240     }
3241     if (tex_rt_dest64) {
3242         if (surf_tex_rt_dest64)
3243             IDirect3DSurface9_Release(surf_tex_rt_dest64);
3244         IDirect3DTexture9_Release(tex_rt_dest64);
3245     }
3246     if (tex_rt_dest640_480) {
3247         if (surf_tex_rt_dest640_480)
3248             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
3249         IDirect3DTexture9_Release(tex_rt_dest640_480);
3250     }
3251     if (tex32) {
3252         if (surf_tex32)
3253             IDirect3DSurface9_Release(surf_tex32);
3254         IDirect3DTexture9_Release(tex32);
3255     }
3256     if (tex64) {
3257         if (surf_tex64)
3258             IDirect3DSurface9_Release(surf_tex64);
3259         IDirect3DTexture9_Release(tex64);
3260     }
3261     if (tex_dest64) {
3262         if (surf_tex_dest64)
3263             IDirect3DSurface9_Release(surf_tex_dest64);
3264         IDirect3DTexture9_Release(tex_dest64);
3265     }
3266
3267     if (orig_rt) {
3268         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3269         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3270         IDirect3DSurface9_Release(orig_rt);
3271     }
3272 }
3273
3274 static void maxmip_test(IDirect3DDevice9 *device)
3275 {
3276     IDirect3DTexture9 *texture = NULL;
3277     IDirect3DSurface9 *surface = NULL;
3278     HRESULT hr;
3279     DWORD color;
3280     static const struct
3281     {
3282         struct
3283         {
3284             float x, y, z;
3285             float s, t;
3286         }
3287         v[4];
3288     }
3289     quads[] =
3290     {
3291         {{
3292             {-1.0, -1.0,  0.0,  0.0,  0.0},
3293             {-1.0,  0.0,  0.0,  0.0,  1.0},
3294             { 0.0, -1.0,  0.0,  1.0,  0.0},
3295             { 0.0,  0.0,  0.0,  1.0,  1.0},
3296         }},
3297         {{
3298             { 0.0, -1.0,  0.0,  0.0,  0.0},
3299             { 0.0,  0.0,  0.0,  0.0,  1.0},
3300             { 1.0, -1.0,  0.0,  1.0,  0.0},
3301             { 1.0,  0.0,  0.0,  1.0,  1.0},
3302         }},
3303         {{
3304             { 0.0,  0.0,  0.0,  0.0,  0.0},
3305             { 0.0,  1.0,  0.0,  0.0,  1.0},
3306             { 1.0,  0.0,  0.0,  1.0,  0.0},
3307             { 1.0,  1.0,  0.0,  1.0,  1.0},
3308         }},
3309         {{
3310             {-1.0,  0.0,  0.0,  0.0,  0.0},
3311             {-1.0,  1.0,  0.0,  0.0,  1.0},
3312             { 0.0,  0.0,  0.0,  1.0,  0.0},
3313             { 0.0,  1.0,  0.0,  1.0,  1.0},
3314         }},
3315     };
3316
3317     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3318                                         &texture, NULL);
3319     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3320     if(!texture)
3321     {
3322         skip("Failed to create test texture\n");
3323         return;
3324     }
3325
3326     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3327     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3328     fill_surface(surface, 0xffff0000);
3329     IDirect3DSurface9_Release(surface);
3330     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3331     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3332     fill_surface(surface, 0xff00ff00);
3333     IDirect3DSurface9_Release(surface);
3334     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3335     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3336     fill_surface(surface, 0xff0000ff);
3337     IDirect3DSurface9_Release(surface);
3338
3339     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3340     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3341     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3342     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3343
3344     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3345     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3346
3347     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3348     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3349
3350     hr = IDirect3DDevice9_BeginScene(device);
3351     if(SUCCEEDED(hr))
3352     {
3353         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3354         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3355         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3356         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3357
3358         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3359         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3360         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3361         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3362
3363         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3364         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3365         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3366         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3367
3368         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3369         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3370         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3371         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3372         hr = IDirect3DDevice9_EndScene(device);
3373         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3374     }
3375
3376     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3377     color = getPixelColor(device, 160, 360);
3378     ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3379     color = getPixelColor(device, 480, 360);
3380     ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3381     color = getPixelColor(device, 480, 120);
3382     ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3383     color = getPixelColor(device, 160, 120);
3384     ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3385     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3386     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3387
3388     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3389     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3390
3391     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3392     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3393
3394     hr = IDirect3DDevice9_BeginScene(device);
3395     if(SUCCEEDED(hr))
3396     {
3397         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3398         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3399         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3400         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3401
3402         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3403         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3404         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3405         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3406
3407         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3408         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3409         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3410         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3411
3412         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3413         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3414         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3415         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3416         hr = IDirect3DDevice9_EndScene(device);
3417         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3418     }
3419
3420     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3421      * level 3 (> levels in texture) samples from the highest level in the
3422      * texture (level 2). */
3423     color = getPixelColor(device, 160, 360);
3424     ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3425     color = getPixelColor(device, 480, 360);
3426     ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3427     color = getPixelColor(device, 480, 120);
3428     ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3429     color = getPixelColor(device, 160, 120);
3430     ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3431     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3432     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3433
3434     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3435     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3436
3437     hr = IDirect3DDevice9_BeginScene(device);
3438     if(SUCCEEDED(hr))
3439     {
3440         DWORD ret;
3441
3442         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3443         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3444         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3445         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3446         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3447         ret = IDirect3DTexture9_SetLOD(texture, 1);
3448         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3449         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3450         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3451
3452         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3453         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3454         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3455         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3456         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3457         ret = IDirect3DTexture9_SetLOD(texture, 2);
3458         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3459         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3460         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3461
3462         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3463         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3464         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3465         ret = IDirect3DTexture9_SetLOD(texture, 1);
3466         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3467         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3468         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3469
3470         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3471         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3472         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3473         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3474         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3475         ret = IDirect3DTexture9_SetLOD(texture, 1);
3476         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3477         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3478         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3479         hr = IDirect3DDevice9_EndScene(device);
3480         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3481     }
3482
3483     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3484      * level 3 (> levels in texture) samples from the highest level in the
3485      * texture (level 2). */
3486     color = getPixelColor(device, 160, 360);
3487     ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3488     color = getPixelColor(device, 480, 360);
3489     ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3490     color = getPixelColor(device, 480, 120);
3491     ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3492     color = getPixelColor(device, 160, 120);
3493     ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3494
3495     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3496     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3497
3498     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3499     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3500     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3501     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3502     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3503     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3504     IDirect3DTexture9_Release(texture);
3505 }
3506
3507 static void release_buffer_test(IDirect3DDevice9 *device)
3508 {
3509     IDirect3DVertexBuffer9 *vb = NULL;
3510     IDirect3DIndexBuffer9 *ib = NULL;
3511     HRESULT hr;
3512     BYTE *data;
3513     LONG ref;
3514
3515     static const struct vertex quad[] = {
3516         {-1.0,      -1.0,       0.1,        0xffff0000},
3517         {-1.0,       1.0,       0.1,        0xffff0000},
3518         { 1.0,       1.0,       0.1,        0xffff0000},
3519
3520         {-1.0,      -1.0,       0.1,        0xff00ff00},
3521         {-1.0,       1.0,       0.1,        0xff00ff00},
3522         { 1.0,       1.0,       0.1,        0xff00ff00}
3523     };
3524     short indices[] = {3, 4, 5};
3525
3526     /* Index and vertex buffers should always be creatable */
3527     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3528                                               D3DPOOL_MANAGED, &vb, NULL);
3529     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3530     if(!vb) {
3531         skip("Failed to create a vertex buffer\n");
3532         return;
3533     }
3534     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3535     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3536     if(!ib) {
3537         skip("Failed to create an index buffer\n");
3538         return;
3539     }
3540
3541     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3542     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3543     memcpy(data, quad, sizeof(quad));
3544     hr = IDirect3DVertexBuffer9_Unlock(vb);
3545     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3546
3547     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3548     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3549     memcpy(data, indices, sizeof(indices));
3550     hr = IDirect3DIndexBuffer9_Unlock(ib);
3551     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3552
3553     hr = IDirect3DDevice9_SetIndices(device, ib);
3554     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3555     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3556     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3557     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3558     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3559
3560     /* Now destroy the bound index buffer and draw again */
3561     ref = IDirect3DIndexBuffer9_Release(ib);
3562     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3563
3564     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3565     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3566
3567     hr = IDirect3DDevice9_BeginScene(device);
3568     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3569     if(SUCCEEDED(hr))
3570     {
3571         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3572          * making assumptions about the indices or vertices
3573          */
3574         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3575         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3576         hr = IDirect3DDevice9_EndScene(device);
3577         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3578     }
3579
3580     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3581     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3582
3583     hr = IDirect3DDevice9_SetIndices(device, NULL);
3584     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3585     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3586     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3587
3588     /* Index buffer was already destroyed as part of the test */
3589     IDirect3DVertexBuffer9_Release(vb);
3590 }
3591
3592 static void float_texture_test(IDirect3DDevice9 *device)
3593 {
3594     IDirect3D9 *d3d = NULL;
3595     HRESULT hr;
3596     IDirect3DTexture9 *texture = NULL;
3597     D3DLOCKED_RECT lr;
3598     float *data;
3599     DWORD color;
3600     float quad[] = {
3601         -1.0,      -1.0,       0.1,     0.0,    0.0,
3602         -1.0,       1.0,       0.1,     0.0,    1.0,
3603          1.0,      -1.0,       0.1,     1.0,    0.0,
3604          1.0,       1.0,       0.1,     1.0,    1.0,
3605     };
3606
3607     memset(&lr, 0, sizeof(lr));
3608     IDirect3DDevice9_GetDirect3D(device, &d3d);
3609     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3610                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3611         skip("D3DFMT_R32F textures not supported\n");
3612         goto out;
3613     }
3614
3615     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3616                                         D3DPOOL_MANAGED, &texture, NULL);
3617     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3618     if(!texture) {
3619         skip("Failed to create R32F texture\n");
3620         goto out;
3621     }
3622
3623     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3624     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3625     data = lr.pBits;
3626     *data = 0.0;
3627     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3628     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3629
3630     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3631     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3632
3633     hr = IDirect3DDevice9_BeginScene(device);
3634     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3635     if(SUCCEEDED(hr))
3636     {
3637         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3638         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3639
3640         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * 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     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3647     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3648
3649     color = getPixelColor(device, 240, 320);
3650     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3651
3652     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3653     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3654
3655 out:
3656     if(texture) IDirect3DTexture9_Release(texture);
3657     IDirect3D9_Release(d3d);
3658 }
3659
3660 static void g16r16_texture_test(IDirect3DDevice9 *device)
3661 {
3662     IDirect3D9 *d3d = NULL;
3663     HRESULT hr;
3664     IDirect3DTexture9 *texture = NULL;
3665     D3DLOCKED_RECT lr;
3666     DWORD *data;
3667     DWORD color;
3668     float quad[] = {
3669        -1.0,      -1.0,       0.1,     0.0,    0.0,
3670        -1.0,       1.0,       0.1,     0.0,    1.0,
3671         1.0,      -1.0,       0.1,     1.0,    0.0,
3672         1.0,       1.0,       0.1,     1.0,    1.0,
3673     };
3674
3675     memset(&lr, 0, sizeof(lr));
3676     IDirect3DDevice9_GetDirect3D(device, &d3d);
3677     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3678        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3679            skip("D3DFMT_G16R16 textures not supported\n");
3680            goto out;
3681     }
3682
3683     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3684                                         D3DPOOL_MANAGED, &texture, NULL);
3685     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3686     if(!texture) {
3687         skip("Failed to create D3DFMT_G16R16 texture\n");
3688         goto out;
3689     }
3690
3691     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3692     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3693     data = lr.pBits;
3694     *data = 0x0f00f000;
3695     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3696     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3697
3698     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3699     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3700
3701     hr = IDirect3DDevice9_BeginScene(device);
3702     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3703     if(SUCCEEDED(hr))
3704     {
3705         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3706         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3707
3708         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3709         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3710
3711         hr = IDirect3DDevice9_EndScene(device);
3712         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3713     }
3714     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3715     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3716
3717     color = getPixelColor(device, 240, 320);
3718     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3719        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3720
3721     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3722     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3723
3724 out:
3725     if(texture) IDirect3DTexture9_Release(texture);
3726     IDirect3D9_Release(d3d);
3727 }
3728
3729 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
3730 {
3731     LONG x_coords[2][2] =
3732     {
3733         {r.left - 1, r.left + 1},
3734         {r.right + 1, r.right - 1},
3735     };
3736     LONG y_coords[2][2] =
3737     {
3738         {r.top - 1, r.top + 1},
3739         {r.bottom + 1, r.bottom - 1}
3740     };
3741     unsigned int i, j, x_side, y_side;
3742
3743     for (i = 0; i < 2; ++i)
3744     {
3745         for (j = 0; j < 2; ++j)
3746         {
3747             for (x_side = 0; x_side < 2; ++x_side)
3748             {
3749                 for (y_side = 0; y_side < 2; ++y_side)
3750                 {
3751                     unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
3752                     DWORD color;
3753                     DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
3754
3755                     color = getPixelColor(device, x, y);
3756                     ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
3757                             message, x, y, color, expected);
3758                 }
3759             }
3760         }
3761     }
3762 }
3763
3764 struct projected_textures_test_run
3765 {
3766     const char *message;
3767     DWORD flags;
3768     IDirect3DVertexDeclaration9 *decl;
3769     BOOL vs, ps;
3770     RECT rect;
3771 };
3772
3773 static void projected_textures_test(IDirect3DDevice9 *device,
3774         struct projected_textures_test_run tests[4])
3775 {
3776     unsigned int i;
3777
3778     static const DWORD vertex_shader[] =
3779     {
3780         0xfffe0101,                                     /* vs_1_1           */
3781         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
3782         0x0000001f, 0x80000005, 0x900f0001,             /* dcl_texcoord0 v1 */
3783         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
3784         0x00000001, 0xe00f0000, 0x90e40001,             /* mov oT0, v1      */
3785         0x0000ffff                                      /* end              */
3786     };
3787     static const DWORD pixel_shader[] =
3788     {
3789         0xffff0103,                                     /* ps_1_3           */
3790         0x00000042, 0xb00f0000,                         /* tex t0           */
3791         0x00000001, 0x800f0000, 0xb0e40000,             /* mov r0, t0       */
3792         0x0000ffff                                      /* end              */
3793     };
3794     IDirect3DVertexShader9 *vs = NULL;
3795     IDirect3DPixelShader9 *ps = NULL;
3796     HRESULT hr;
3797
3798     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
3799     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
3800     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
3801     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3802
3803     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
3804     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3805
3806     hr = IDirect3DDevice9_BeginScene(device);
3807     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3808     if (FAILED(hr))
3809         return;
3810
3811     for (i = 0; i < 4; ++i)
3812     {
3813         DWORD value = 0xdeadbeef;
3814         static const float proj_quads[] =
3815         {
3816             -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3817              0.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3818             -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3819              0.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3820
3821              0.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3822              1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3823              0.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3824              1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3825
3826             -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3827              0.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3828             -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3829              0.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3830
3831              0.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3832              1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3833              0.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3834              1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3835         };
3836
3837         if (tests[i].vs)
3838             hr = IDirect3DDevice9_SetVertexShader(device, vs);
3839         else
3840             hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3841         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
3842         if (tests[i].ps)
3843             hr = IDirect3DDevice9_SetPixelShader(device, ps);
3844         else
3845             hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3846         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3847
3848         hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
3849         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3850
3851         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
3852         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3853         hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
3854         ok(SUCCEEDED(hr) && value == tests[i].flags,
3855                 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
3856
3857         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
3858                 &proj_quads[i * 4 * 7], 7 * sizeof(float));
3859         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3860     }
3861
3862     hr = IDirect3DDevice9_EndScene(device);
3863     ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3864
3865     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3866     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3867     IDirect3DVertexShader9_Release(vs);
3868     IDirect3DPixelShader9_Release(ps);
3869
3870     for (i = 0; i < 4; ++i)
3871         check_rect(device, tests[i].rect, tests[i].message);
3872
3873     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3874     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3875 }
3876
3877 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3878 {
3879     HRESULT hr;
3880     IDirect3D9 *d3d;
3881     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3882     D3DCAPS9 caps;
3883     IDirect3DTexture9 *texture = NULL;
3884     IDirect3DVolumeTexture9 *volume = NULL;
3885     unsigned int x, y, z;
3886     D3DLOCKED_RECT lr;
3887     D3DLOCKED_BOX lb;
3888     DWORD color;
3889     UINT w, h;
3890     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
3891     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3892                            0.0, 1.0, 0.0, 0.0,
3893                            0.0, 0.0, 1.0, 0.0,
3894                            0.0, 0.0, 0.0, 1.0};
3895     static const D3DVERTEXELEMENT9 decl_elements[] = {
3896         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3897         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3898         D3DDECL_END()
3899     };
3900     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3901         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3902         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3903         D3DDECL_END()
3904     };
3905     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3906         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3907         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3908         D3DDECL_END()
3909     };
3910     static const D3DVERTEXELEMENT9 decl_elements4[] = {
3911         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3912         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3913         D3DDECL_END()
3914     };
3915     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3916                                                  0x00, 0xff, 0x00, 0x00,
3917                                                  0x00, 0x00, 0x00, 0x00,
3918                                                  0x00, 0x00, 0x00, 0x00};
3919
3920     memset(&lr, 0, sizeof(lr));
3921     memset(&lb, 0, sizeof(lb));
3922     IDirect3DDevice9_GetDirect3D(device, &d3d);
3923     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3924                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3925         fmt = D3DFMT_A16B16G16R16;
3926     }
3927     IDirect3D9_Release(d3d);
3928
3929     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3930     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3931     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3932     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3933     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3934     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3935     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
3936     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3937     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3938     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3939     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3940     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3941     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3942     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3943     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3944     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3945     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3946     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3947     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3948     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3949     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3950     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3951     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3952     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3953     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3954     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3955
3956     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3957     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3958     w = min(1024, caps.MaxTextureWidth);
3959     h = min(1024, caps.MaxTextureHeight);
3960     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3961                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3962     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3963     if(!texture) {
3964         skip("Failed to create the test texture\n");
3965         return;
3966     }
3967
3968     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3969      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3970      * 1.0 in red and green for the x and y coords
3971      */
3972     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3973     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3974     for(y = 0; y < h; y++) {
3975         for(x = 0; x < w; x++) {
3976             double r_f = (double) y / (double) h;
3977             double g_f = (double) x / (double) w;
3978             if(fmt == D3DFMT_A16B16G16R16) {
3979                 unsigned short r, g;
3980                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3981                 r = (unsigned short) (r_f * 65536.0);
3982                 g = (unsigned short) (g_f * 65536.0);
3983                 dst[0] = r;
3984                 dst[1] = g;
3985                 dst[2] = 0;
3986                 dst[3] = 65535;
3987             } else {
3988                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3989                 unsigned char r = (unsigned char) (r_f * 255.0);
3990                 unsigned char g = (unsigned char) (g_f * 255.0);
3991                 dst[0] = 0;
3992                 dst[1] = g;
3993                 dst[2] = r;
3994                 dst[3] = 255;
3995             }
3996         }
3997     }
3998     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3999     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4000     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4001     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4002
4003     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4004     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4005     hr = IDirect3DDevice9_BeginScene(device);
4006     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4007     if(SUCCEEDED(hr))
4008     {
4009         float quad1[] = {
4010             -1.0,      -1.0,       0.1,     1.0,    1.0,
4011             -1.0,       0.0,       0.1,     1.0,    1.0,
4012              0.0,      -1.0,       0.1,     1.0,    1.0,
4013              0.0,       0.0,       0.1,     1.0,    1.0,
4014         };
4015         float quad2[] = {
4016             -1.0,       0.0,       0.1,     1.0,    1.0,
4017             -1.0,       1.0,       0.1,     1.0,    1.0,
4018              0.0,       0.0,       0.1,     1.0,    1.0,
4019              0.0,       1.0,       0.1,     1.0,    1.0,
4020         };
4021         float quad3[] = {
4022              0.0,       0.0,       0.1,     0.5,    0.5,
4023              0.0,       1.0,       0.1,     0.5,    0.5,
4024              1.0,       0.0,       0.1,     0.5,    0.5,
4025              1.0,       1.0,       0.1,     0.5,    0.5,
4026         };
4027         float quad4[] = {
4028              320,       480,       0.1,     1.0,    0.0,    1.0,
4029              320,       240,       0.1,     1.0,    0.0,    1.0,
4030              640,       480,       0.1,     1.0,    0.0,    1.0,
4031              640,       240,       0.1,     1.0,    0.0,    1.0,
4032         };
4033         float mat[16] = {0.0, 0.0, 0.0, 0.0,
4034                           0.0, 0.0, 0.0, 0.0,
4035                           0.0, 0.0, 0.0, 0.0,
4036                           0.0, 0.0, 0.0, 0.0};
4037
4038         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4039         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4040         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4041         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4042         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4043
4044         /* What happens with transforms enabled? */
4045         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4046         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4047         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4048         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4049
4050         /* What happens if 4 coords are used, but only 2 given ?*/
4051         mat[8] = 1.0;
4052         mat[13] = 1.0;
4053         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4054         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4055         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4056         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4057         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4058         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4059
4060         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4061          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4062          * due to the coords in the vertices. (turns out red, indeed)
4063          */
4064         memset(mat, 0, sizeof(mat));
4065         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4066         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4067         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4068         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4069         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4070         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4071         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4072         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4073
4074         hr = IDirect3DDevice9_EndScene(device);
4075         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4076     }
4077     color = getPixelColor(device, 160, 360);
4078     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
4079     color = getPixelColor(device, 160, 120);
4080     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4081     color = getPixelColor(device, 480, 120);
4082     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
4083     color = getPixelColor(device, 480, 360);
4084     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
4085     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4086     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4087
4088     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4089     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4090
4091     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4092     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4093     hr = IDirect3DDevice9_BeginScene(device);
4094     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4095     if(SUCCEEDED(hr))
4096     {
4097         float quad1[] = {
4098             -1.0,      -1.0,       0.1,     0.8,    0.2,
4099             -1.0,       0.0,       0.1,     0.8,    0.2,
4100              0.0,      -1.0,       0.1,     0.8,    0.2,
4101              0.0,       0.0,       0.1,     0.8,    0.2,
4102         };
4103         float quad2[] = {
4104             -1.0,       0.0,       0.1,     0.5,    1.0,
4105             -1.0,       1.0,       0.1,     0.5,    1.0,
4106              0.0,       0.0,       0.1,     0.5,    1.0,
4107              0.0,       1.0,       0.1,     0.5,    1.0,
4108         };
4109         float quad3[] = {
4110              0.0,       0.0,       0.1,     0.5,    1.0,
4111              0.0,       1.0,       0.1,     0.5,    1.0,
4112              1.0,       0.0,       0.1,     0.5,    1.0,
4113              1.0,       1.0,       0.1,     0.5,    1.0,
4114         };
4115         float quad4[] = {
4116              0.0,      -1.0,       0.1,     0.8,    0.2,
4117              0.0,       0.0,       0.1,     0.8,    0.2,
4118              1.0,      -1.0,       0.1,     0.8,    0.2,
4119              1.0,       0.0,       0.1,     0.8,    0.2,
4120         };
4121         float mat[16] = {0.0, 0.0, 0.0, 0.0,
4122                           0.0, 0.0, 0.0, 0.0,
4123                           0.0, 1.0, 0.0, 0.0,
4124                           0.0, 0.0, 0.0, 0.0};
4125
4126         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
4127          */
4128         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4129         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4130         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4131         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4132
4133         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4134         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4135
4136         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
4137          * it behaves like COUNT2 because normal textures require 2 coords
4138          */
4139         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4140         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4141         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
4142         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4143
4144         /* Just to be sure, the same as quad2 above */
4145         memset(mat, 0, sizeof(mat));
4146         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4147         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4148         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4149         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4150         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4151         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4152
4153         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
4154          * used? And what happens to the first?
4155          */
4156         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4157         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4158         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4159         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4160
4161         hr = IDirect3DDevice9_EndScene(device);
4162         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4163     }
4164     color = getPixelColor(device, 160, 360);
4165     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
4166     color = getPixelColor(device, 160, 120);
4167     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4168     color = getPixelColor(device, 480, 120);
4169     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
4170        "quad 3 has color %08x, expected 0x00ff8000\n", color);
4171     color = getPixelColor(device, 480, 360);
4172     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
4173        "quad 4 has color %08x, expected 0x0033cc00\n", color);
4174     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4175     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4176
4177     IDirect3DTexture9_Release(texture);
4178
4179     /* Test projected textures, without any fancy matrices */
4180     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
4181     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4182     if (SUCCEEDED(hr))
4183     {
4184         struct projected_textures_test_run projected_tests_1[4] =
4185         {
4186             {
4187                 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
4188                 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
4189                 decl3,
4190                 FALSE, TRUE,
4191                 {120, 300, 240, 390},
4192             },
4193             {
4194                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
4195                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4196                 decl3,
4197                 FALSE, TRUE,
4198                 {400, 360, 480, 420},
4199             },
4200             /* Try with some invalid values */
4201             {
4202                 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
4203                 0xffffffff,
4204                 decl3,
4205                 FALSE, TRUE,
4206                 {120, 60, 240, 150}
4207             },
4208             {
4209                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
4210                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4211                 decl4,
4212                 FALSE, TRUE,
4213                 {340, 210, 360, 225},
4214             }
4215         };
4216         struct projected_textures_test_run projected_tests_2[4] =
4217         {
4218             {
4219                 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
4220                 D3DTTFF_PROJECTED,
4221                 decl3,
4222                 FALSE, TRUE,
4223                 {120, 300, 240, 390},
4224             },
4225             {
4226                 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
4227                 D3DTTFF_PROJECTED,
4228                 decl,
4229                 FALSE, TRUE,
4230                 {400, 360, 480, 420},
4231             },
4232             {
4233                 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
4234                 0xffffffff,
4235                 decl,
4236                 FALSE, TRUE,
4237                 {80, 120, 160, 180},
4238             },
4239             {
4240                 "D3DTTFF_COUNT1 (draws non-projected) - top right",
4241                 D3DTTFF_COUNT1,
4242                 decl4,
4243                 FALSE, TRUE,
4244                 {340, 210, 360, 225},
4245             }
4246         };
4247         struct projected_textures_test_run projected_tests_3[4] =
4248         {
4249             {
4250                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
4251                 D3DTTFF_PROJECTED,
4252                 decl3,
4253                 TRUE, FALSE,
4254                 {120, 300, 240, 390},
4255             },
4256             {
4257                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
4258                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4259                 decl3,
4260                 TRUE, TRUE,
4261                 {440, 300, 560, 390},
4262             },
4263             {
4264                 "0xffffffff (like COUNT4 | PROJECTED) - top left",
4265                 0xffffffff,
4266                 decl3,
4267                 TRUE, TRUE,
4268                 {120, 60, 240, 150},
4269             },
4270             {
4271                 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
4272                 D3DTTFF_PROJECTED,
4273                 decl3,
4274                 FALSE, FALSE,
4275                 {440, 60, 560, 150},
4276             },
4277         };
4278
4279         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4280         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4281
4282         hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4283         ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4284         for(x = 0; x < 4; x++) {
4285             memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
4286         }
4287         hr = IDirect3DTexture9_UnlockRect(texture, 0);
4288         ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4289         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4290         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4291
4292         projected_textures_test(device, projected_tests_1);
4293         projected_textures_test(device, projected_tests_2);
4294         projected_textures_test(device, projected_tests_3);
4295
4296         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4297         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4298         IDirect3DTexture9_Release(texture);
4299     }
4300
4301     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
4302     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4303     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
4304      * Thus watch out if sampling from texels between 0 and 1.
4305      */
4306     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
4307     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
4308        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
4309     if(!volume) {
4310         skip("Failed to create a volume texture\n");
4311         goto out;
4312     }
4313
4314     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
4315     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
4316     for(z = 0; z < 32; z++) {
4317         for(y = 0; y < 32; y++) {
4318             for(x = 0; x < 32; x++) {
4319                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
4320                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
4321                 float r_f = (float) x / 31.0;
4322                 float g_f = (float) y / 31.0;
4323                 float b_f = (float) z / 31.0;
4324
4325                 if(fmt == D3DFMT_A16B16G16R16) {
4326                     unsigned short *mem_s = mem;
4327                     mem_s[0]  = r_f * 65535.0;
4328                     mem_s[1]  = g_f * 65535.0;
4329                     mem_s[2]  = b_f * 65535.0;
4330                     mem_s[3]  = 65535;
4331                 } else {
4332                     unsigned char *mem_c = mem;
4333                     mem_c[0]  = b_f * 255.0;
4334                     mem_c[1]  = g_f * 255.0;
4335                     mem_c[2]  = r_f * 255.0;
4336                     mem_c[3]  = 255;
4337                 }
4338             }
4339         }
4340     }
4341     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
4342     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4343
4344     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
4345     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4346
4347     hr = IDirect3DDevice9_BeginScene(device);
4348     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4349     if(SUCCEEDED(hr))
4350     {
4351         float quad1[] = {
4352             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4353             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4354              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4355              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4356         };
4357         float quad2[] = {
4358             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4359             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
4360              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4361              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
4362         };
4363         float quad3[] = {
4364              0.0,       0.0,       0.1,     0.0,    0.0,
4365              0.0,       1.0,       0.1,     0.0,    0.0,
4366              1.0,       0.0,       0.1,     0.0,    0.0,
4367              1.0,       1.0,       0.1,     0.0,    0.0
4368         };
4369         float quad4[] = {
4370              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4371              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4372              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4373              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
4374         };
4375         float mat[16] = {1.0, 0.0, 0.0, 0.0,
4376                          0.0, 0.0, 1.0, 0.0,
4377                          0.0, 1.0, 0.0, 0.0,
4378                          0.0, 0.0, 0.0, 1.0};
4379         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4380         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4381
4382         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
4383          * values
4384          */
4385         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4386         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4387         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4388         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4389         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4390         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4391
4392         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
4393          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
4394          * otherwise the w will be missing(blue).
4395          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
4396          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
4397          */
4398         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4399         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4400         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4401         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4402
4403         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
4404         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4405         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4406         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4407         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4408         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4409         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4410         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4411         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4412
4413         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4414          * disable. ATI extends it up to the amount of values needed for the volume texture
4415          */
4416         memset(mat, 0, sizeof(mat));
4417         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4418         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4419         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4420         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4421         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4422         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4423         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4424         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4425
4426         hr = IDirect3DDevice9_EndScene(device);
4427         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4428     }
4429
4430     color = getPixelColor(device, 160, 360);
4431     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4432     color = getPixelColor(device, 160, 120);
4433     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4434        "quad 2 has color %08x, expected 0x00ffff00\n", color);
4435     color = getPixelColor(device, 480, 120);
4436     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4437     color = getPixelColor(device, 480, 360);
4438     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4439
4440     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4441     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4442
4443     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4444     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4445     hr = IDirect3DDevice9_BeginScene(device);
4446     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4447     if(SUCCEEDED(hr))
4448     {
4449         float quad1[] = {
4450             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4451             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4452              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4453              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4454         };
4455         float quad2[] = {
4456             -1.0,       0.0,       0.1,
4457             -1.0,       1.0,       0.1,
4458              0.0,       0.0,       0.1,
4459              0.0,       1.0,       0.1,
4460         };
4461         float quad3[] = {
4462              0.0,       0.0,       0.1,     1.0,
4463              0.0,       1.0,       0.1,     1.0,
4464              1.0,       0.0,       0.1,     1.0,
4465              1.0,       1.0,       0.1,     1.0
4466         };
4467         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4468                            0.0, 0.0, 0.0, 0.0,
4469                            0.0, 0.0, 0.0, 0.0,
4470                            0.0, 1.0, 0.0, 0.0};
4471         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4472                            1.0, 0.0, 0.0, 0.0,
4473                            0.0, 1.0, 0.0, 0.0,
4474                            0.0, 0.0, 1.0, 0.0};
4475         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4476         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4477
4478         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4479          * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4480          * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4481          * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4482          * 4th *input* coordinate.
4483          */
4484         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4485         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4486         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4487         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4488         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4489         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4490
4491         /* None passed */
4492         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4493         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4494         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4495         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4496         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4497         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4498
4499         /* 4 used, 1 passed */
4500         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4501         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4502         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4503         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4504         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4505         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4506
4507         hr = IDirect3DDevice9_EndScene(device);
4508         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4509     }
4510     color = getPixelColor(device, 160, 360);
4511     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4512     color = getPixelColor(device, 160, 120);
4513     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4514     color = getPixelColor(device, 480, 120);
4515     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4516     /* Quad4: unused */
4517
4518     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4519     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4520
4521     IDirect3DVolumeTexture9_Release(volume);
4522
4523     out:
4524     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4525     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4526     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4527     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4528     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4529     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4530     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4531     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4532     IDirect3DVertexDeclaration9_Release(decl);
4533     IDirect3DVertexDeclaration9_Release(decl2);
4534     IDirect3DVertexDeclaration9_Release(decl3);
4535     IDirect3DVertexDeclaration9_Release(decl4);
4536 }
4537
4538 static void texdepth_test(IDirect3DDevice9 *device)
4539 {
4540     IDirect3DPixelShader9 *shader;
4541     HRESULT hr;
4542     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4543     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4544     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4545     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4546     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4547     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4548     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4549     DWORD shader_code[] = {
4550         0xffff0104,                                                                 /* ps_1_4               */
4551         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4552         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4553         0x0000fffd,                                                                 /* phase                */
4554         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4555         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4556         0x0000ffff                                                                  /* end                  */
4557     };
4558     DWORD color;
4559     float vertex[] = {
4560        -1.0,   -1.0,    0.0,
4561         1.0,   -1.0,    1.0,
4562        -1.0,    1.0,    0.0,
4563         1.0,    1.0,    1.0
4564     };
4565
4566     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4567     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4568
4569     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4570     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4571     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4572     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4573     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4574     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4575     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4576     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4577     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4578     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4579
4580     /* Fill the depth buffer with a gradient */
4581     hr = IDirect3DDevice9_BeginScene(device);
4582     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4583     if(SUCCEEDED(hr))
4584     {
4585         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4586         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4587         hr = IDirect3DDevice9_EndScene(device);
4588         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4589     }
4590
4591     /* Now perform the actual tests. Same geometry, but with the shader */
4592     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4593     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4594     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4595     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4596     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4597     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4598
4599     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4600     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4601     hr = IDirect3DDevice9_BeginScene(device);
4602     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4603     if(SUCCEEDED(hr))
4604     {
4605         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4606         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4607
4608         hr = IDirect3DDevice9_EndScene(device);
4609         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4610     }
4611
4612     color = getPixelColor(device, 158, 240);
4613     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4614     color = getPixelColor(device, 162, 240);
4615     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4616
4617     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4618     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4619
4620     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4621     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4622
4623     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4624     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4625     hr = IDirect3DDevice9_BeginScene(device);
4626     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4627     if(SUCCEEDED(hr))
4628     {
4629         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4630         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4631
4632         hr = IDirect3DDevice9_EndScene(device);
4633         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4634     }
4635
4636     color = getPixelColor(device, 318, 240);
4637     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4638     color = getPixelColor(device, 322, 240);
4639     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4640
4641     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4642     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4643
4644     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4645     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4646
4647     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4648     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4649     hr = IDirect3DDevice9_BeginScene(device);
4650     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4651     if(SUCCEEDED(hr))
4652     {
4653         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4654         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4655
4656         hr = IDirect3DDevice9_EndScene(device);
4657         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4658     }
4659
4660     color = getPixelColor(device, 1, 240);
4661     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4662
4663     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4664     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4665
4666     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4667     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4668
4669     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4670     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4671     hr = IDirect3DDevice9_BeginScene(device);
4672     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4673     if(SUCCEEDED(hr))
4674     {
4675         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4676         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4677
4678         hr = IDirect3DDevice9_EndScene(device);
4679         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4680     }
4681     color = getPixelColor(device, 318, 240);
4682     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4683     color = getPixelColor(device, 322, 240);
4684     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4685
4686     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4687     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4688
4689     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4690     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4691
4692     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4693     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4694     hr = IDirect3DDevice9_BeginScene(device);
4695     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4696     if(SUCCEEDED(hr))
4697     {
4698         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4699         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4700
4701         hr = IDirect3DDevice9_EndScene(device);
4702         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4703     }
4704
4705     color = getPixelColor(device, 1, 240);
4706     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4707
4708     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4709     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4710
4711     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4712     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4713
4714     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4715     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4716     hr = IDirect3DDevice9_BeginScene(device);
4717     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4718     if(SUCCEEDED(hr))
4719     {
4720         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4721         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4722
4723         hr = IDirect3DDevice9_EndScene(device);
4724         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4725     }
4726
4727     color = getPixelColor(device, 638, 240);
4728     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4729
4730     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4731     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4732
4733     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4734     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4735
4736     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4737     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4738     hr = IDirect3DDevice9_BeginScene(device);
4739     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4740     if(SUCCEEDED(hr))
4741     {
4742         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4743         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4744
4745         hr = IDirect3DDevice9_EndScene(device);
4746         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4747     }
4748
4749     color = getPixelColor(device, 638, 240);
4750     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4751
4752     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4753     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4754
4755     /* Cleanup */
4756     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4757     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4758     IDirect3DPixelShader9_Release(shader);
4759
4760     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4761     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4762     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4763     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4764 }
4765
4766 static void texkill_test(IDirect3DDevice9 *device)
4767 {
4768     IDirect3DPixelShader9 *shader;
4769     HRESULT hr;
4770     DWORD color;
4771
4772     const float vertex[] = {
4773     /*                          bottom  top    right    left */
4774         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4775          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4776         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4777          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4778     };
4779
4780     DWORD shader_code_11[] = {
4781     0xffff0101,                                                             /* ps_1_1                     */
4782     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4783     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4784     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4785     0x0000ffff                                                              /* end                        */
4786     };
4787     DWORD shader_code_20[] = {
4788     0xffff0200,                                                             /* ps_2_0                     */
4789     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4790     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4791     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4792     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4793     0x0000ffff                                                              /* end                        */
4794     };
4795
4796     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4797     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4798     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4799     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4800
4801     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4802     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4803     hr = IDirect3DDevice9_BeginScene(device);
4804     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4805     if(SUCCEEDED(hr))
4806     {
4807         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4808         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4809         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4810         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4811         hr = IDirect3DDevice9_EndScene(device);
4812         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4813     }
4814     color = getPixelColor(device, 63, 46);
4815     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4816     color = getPixelColor(device, 66, 46);
4817     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4818     color = getPixelColor(device, 63, 49);
4819     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4820     color = getPixelColor(device, 66, 49);
4821     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4822
4823     color = getPixelColor(device, 578, 46);
4824     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4825     color = getPixelColor(device, 575, 46);
4826     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4827     color = getPixelColor(device, 578, 49);
4828     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4829     color = getPixelColor(device, 575, 49);
4830     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4831
4832     color = getPixelColor(device, 63, 430);
4833     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4834     color = getPixelColor(device, 63, 433);
4835     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4836     color = getPixelColor(device, 66, 433);
4837     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4838     color = getPixelColor(device, 66, 430);
4839     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4840
4841     color = getPixelColor(device, 578, 430);
4842     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4843     color = getPixelColor(device, 578, 433);
4844     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4845     color = getPixelColor(device, 575, 433);
4846     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4847     color = getPixelColor(device, 575, 430);
4848     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4849
4850     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4851     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4852
4853     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4854     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4855     IDirect3DPixelShader9_Release(shader);
4856
4857     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4858     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4859     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4860     if(FAILED(hr)) {
4861         skip("Failed to create 2.0 test shader, most likely not supported\n");
4862         return;
4863     }
4864
4865     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4866     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4867     hr = IDirect3DDevice9_BeginScene(device);
4868     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4869     if(SUCCEEDED(hr))
4870     {
4871         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4872         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4873         hr = IDirect3DDevice9_EndScene(device);
4874         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4875     }
4876
4877     color = getPixelColor(device, 63, 46);
4878     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4879     color = getPixelColor(device, 66, 46);
4880     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4881     color = getPixelColor(device, 63, 49);
4882     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4883     color = getPixelColor(device, 66, 49);
4884     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4885
4886     color = getPixelColor(device, 578, 46);
4887     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4888     color = getPixelColor(device, 575, 46);
4889     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4890     color = getPixelColor(device, 578, 49);
4891     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4892     color = getPixelColor(device, 575, 49);
4893     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4894
4895     color = getPixelColor(device, 63, 430);
4896     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4897     color = getPixelColor(device, 63, 433);
4898     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4899     color = getPixelColor(device, 66, 433);
4900     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4901     color = getPixelColor(device, 66, 430);
4902     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4903
4904     color = getPixelColor(device, 578, 430);
4905     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4906     color = getPixelColor(device, 578, 433);
4907     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4908     color = getPixelColor(device, 575, 433);
4909     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4910     color = getPixelColor(device, 575, 430);
4911     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4912
4913     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4914     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4915
4916     /* Cleanup */
4917     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4918     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4919     IDirect3DPixelShader9_Release(shader);
4920 }
4921
4922 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4923 {
4924     IDirect3D9 *d3d9;
4925     HRESULT hr;
4926     IDirect3DTexture9 *texture;
4927     IDirect3DPixelShader9 *shader;
4928     IDirect3DPixelShader9 *shader2;
4929     D3DLOCKED_RECT lr;
4930     DWORD color;
4931     DWORD shader_code[] = {
4932         0xffff0101,                             /* ps_1_1       */
4933         0x00000042, 0xb00f0000,                 /* tex t0       */
4934         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4935         0x0000ffff                              /* end          */
4936     };
4937     DWORD shader_code2[] = {
4938         0xffff0101,                             /* ps_1_1       */
4939         0x00000042, 0xb00f0000,                 /* tex t0       */
4940         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4941         0x0000ffff                              /* end          */
4942     };
4943
4944     float quad[] = {
4945        -1.0,   -1.0,   0.1,     0.5,    0.5,
4946         1.0,   -1.0,   0.1,     0.5,    0.5,
4947        -1.0,    1.0,   0.1,     0.5,    0.5,
4948         1.0,    1.0,   0.1,     0.5,    0.5,
4949     };
4950
4951     memset(&lr, 0, sizeof(lr));
4952     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4953     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4954                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4955     IDirect3D9_Release(d3d9);
4956     if(FAILED(hr)) {
4957         skip("No D3DFMT_X8L8V8U8 support\n");
4958         return;
4959     };
4960
4961     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4962     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4963
4964     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4965     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4966     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4967     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4968     *((DWORD *) lr.pBits) = 0x11ca3141;
4969     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4970     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4971
4972     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4973     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4974     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4975     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4976
4977     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4978     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4979     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4980     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4981     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4982     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4983
4984     hr = IDirect3DDevice9_BeginScene(device);
4985     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4986     if(SUCCEEDED(hr))
4987     {
4988         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4989         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4990
4991         hr = IDirect3DDevice9_EndScene(device);
4992         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4993     }
4994     color = getPixelColor(device, 578, 430);
4995     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4996        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4997     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4998     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4999
5000     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
5001     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5002     hr = IDirect3DDevice9_BeginScene(device);
5003     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5004     if(SUCCEEDED(hr))
5005     {
5006         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5007         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5008
5009         hr = IDirect3DDevice9_EndScene(device);
5010         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5011     }
5012     color = getPixelColor(device, 578, 430);
5013     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
5014     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5015     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5016
5017     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5018     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5019     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5020     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5021     IDirect3DPixelShader9_Release(shader);
5022     IDirect3DPixelShader9_Release(shader2);
5023     IDirect3DTexture9_Release(texture);
5024 }
5025
5026 static void autogen_mipmap_test(IDirect3DDevice9 *device)
5027 {
5028     HRESULT hr;
5029     IDirect3D9 *d3d;
5030     IDirect3DTexture9 *texture = NULL;
5031     IDirect3DSurface9 *surface;
5032     DWORD color;
5033     const RECT r1 = {256, 256, 512, 512};
5034     const RECT r2 = {512, 256, 768, 512};
5035     const RECT r3 = {256, 512, 512, 768};
5036     const RECT r4 = {512, 512, 768, 768};
5037     unsigned int x, y;
5038     D3DLOCKED_RECT lr;
5039     memset(&lr, 0, sizeof(lr));
5040
5041     IDirect3DDevice9_GetDirect3D(device, &d3d);
5042     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5043        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
5044         skip("No autogenmipmap support\n");
5045         IDirect3D9_Release(d3d);
5046         return;
5047     }
5048     IDirect3D9_Release(d3d);
5049
5050     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5051     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5052
5053     /* Make the mipmap big, so that a smaller mipmap is used
5054      */
5055     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5056                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5057     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5058
5059     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5060     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5061     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5062     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5063     for(y = 0; y < 1024; y++) {
5064         for(x = 0; x < 1024; x++) {
5065             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5066             POINT pt;
5067
5068             pt.x = x;
5069             pt.y = y;
5070             if(PtInRect(&r1, pt)) {
5071                 *dst = 0xffff0000;
5072             } else if(PtInRect(&r2, pt)) {
5073                 *dst = 0xff00ff00;
5074             } else if(PtInRect(&r3, pt)) {
5075                 *dst = 0xff0000ff;
5076             } else if(PtInRect(&r4, pt)) {
5077                 *dst = 0xff000000;
5078             } else {
5079                 *dst = 0xffffffff;
5080             }
5081         }
5082     }
5083     hr = IDirect3DSurface9_UnlockRect(surface);
5084     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5085     IDirect3DSurface9_Release(surface);
5086
5087     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5088     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5089     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5090     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5091
5092     hr = IDirect3DDevice9_BeginScene(device);
5093     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5094     if(SUCCEEDED(hr)) {
5095         const float quad[] =  {
5096            -0.5,   -0.5,    0.1,    0.0,    0.0,
5097            -0.5,    0.5,    0.1,    0.0,    1.0,
5098             0.5,   -0.5,    0.1,    1.0,    0.0,
5099             0.5,    0.5,    0.1,    1.0,    1.0
5100         };
5101
5102         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5103         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5104         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5105         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5106         hr = IDirect3DDevice9_EndScene(device);
5107         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5108     }
5109     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5110     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5111     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
5112     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5113     IDirect3DTexture9_Release(texture);
5114
5115     color = getPixelColor(device, 200, 200);
5116     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5117     color = getPixelColor(device, 280, 200);
5118     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5119     color = getPixelColor(device, 360, 200);
5120     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5121     color = getPixelColor(device, 440, 200);
5122     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5123     color = getPixelColor(device, 200, 270);
5124     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5125     color = getPixelColor(device, 280, 270);
5126     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5127     color = getPixelColor(device, 360, 270);
5128     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5129     color = getPixelColor(device, 440, 270);
5130     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5131     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5132     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5133 }
5134
5135 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
5136 {
5137     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5138     IDirect3DVertexDeclaration9 *decl;
5139     HRESULT hr;
5140     DWORD color;
5141     DWORD shader_code_11[] =  {
5142         0xfffe0101,                                         /* vs_1_1           */
5143         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5144         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5145         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5146         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5147         0x0000ffff                                          /* end              */
5148     };
5149     DWORD shader_code_11_2[] =  {
5150         0xfffe0101,                                         /* vs_1_1           */
5151         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
5152         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
5153         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5154         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5155         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5156         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5157         0x0000ffff                                          /* end              */
5158     };
5159     DWORD shader_code_20[] =  {
5160         0xfffe0200,                                         /* vs_2_0           */
5161         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5162         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5163         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5164         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5165         0x0000ffff                                          /* end              */
5166     };
5167     DWORD shader_code_20_2[] =  {
5168         0xfffe0200,                                         /* vs_2_0           */
5169         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
5170         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
5171         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5172         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5173         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5174         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5175         0x0000ffff                                          /* end              */
5176     };
5177     static const D3DVERTEXELEMENT9 decl_elements[] = {
5178         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5179         D3DDECL_END()
5180     };
5181     float quad1[] = {
5182         -1.0,   -1.0,   0.1,
5183          0.0,   -1.0,   0.1,
5184         -1.0,    0.0,   0.1,
5185          0.0,    0.0,   0.1
5186     };
5187     float quad2[] = {
5188          0.0,   -1.0,   0.1,
5189          1.0,   -1.0,   0.1,
5190          0.0,    0.0,   0.1,
5191          1.0,    0.0,   0.1
5192     };
5193     float quad3[] = {
5194          0.0,    0.0,   0.1,
5195          1.0,    0.0,   0.1,
5196          0.0,    1.0,   0.1,
5197          1.0,    1.0,   0.1
5198     };
5199     float quad4[] = {
5200         -1.0,    0.0,   0.1,
5201          0.0,    0.0,   0.1,
5202         -1.0,    1.0,   0.1,
5203          0.0,    1.0,   0.1
5204     };
5205     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
5206     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
5207
5208     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5209     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5210
5211     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
5212     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5213     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
5214     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5215     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
5216     if(FAILED(hr)) shader_20 = NULL;
5217     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
5218     if(FAILED(hr)) shader_20_2 = NULL;
5219     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5220     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5221
5222     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
5223     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5224     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
5225     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5226     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5227     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5228
5229     hr = IDirect3DDevice9_BeginScene(device);
5230     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5231     if(SUCCEEDED(hr))
5232     {
5233         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
5234         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5235         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5236         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5237
5238         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
5239         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5240         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5241         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5242
5243         if(shader_20) {
5244             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
5245             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5246             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5247             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5248         }
5249
5250         if(shader_20_2) {
5251             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
5252             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5253             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5254             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5255         }
5256
5257         hr = IDirect3DDevice9_EndScene(device);
5258         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5259     }
5260
5261     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5262     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5263     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5264     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5265
5266     color = getPixelColor(device, 160, 360);
5267     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5268        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
5269     color = getPixelColor(device, 480, 360);
5270     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5271        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
5272     if(shader_20) {
5273         color = getPixelColor(device, 480, 120);
5274         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5275            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
5276     }
5277     if(shader_20_2) {
5278         color = getPixelColor(device, 160, 120);
5279         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5280            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5281     }
5282     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5283     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5284
5285     IDirect3DVertexDeclaration9_Release(decl);
5286     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
5287     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
5288     IDirect3DVertexShader9_Release(shader_11_2);
5289     IDirect3DVertexShader9_Release(shader_11);
5290 }
5291
5292 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
5293 {
5294     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
5295     HRESULT hr;
5296     DWORD color;
5297     DWORD shader_code_11[] =  {
5298         0xffff0101,                                         /* ps_1_1           */
5299         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5300         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5301         0x0000ffff                                          /* end              */
5302     };
5303     DWORD shader_code_12[] =  {
5304         0xffff0102,                                         /* ps_1_2           */
5305         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5306         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5307         0x0000ffff                                          /* end              */
5308     };
5309     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
5310      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
5311      * During development of this test, 1.3 shaders were verified too
5312      */
5313     DWORD shader_code_14[] =  {
5314         0xffff0104,                                         /* ps_1_4           */
5315         /* Try to make one constant local. It gets clamped too, although the binary contains
5316          * the bigger numbers
5317          */
5318         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
5319         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5320         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5321         0x0000ffff                                          /* end              */
5322     };
5323     DWORD shader_code_20[] =  {
5324         0xffff0200,                                         /* ps_2_0           */
5325         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5326         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5327         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
5328         0x0000ffff                                          /* end              */
5329     };
5330     float quad1[] = {
5331         -1.0,   -1.0,   0.1,
5332          0.0,   -1.0,   0.1,
5333         -1.0,    0.0,   0.1,
5334          0.0,    0.0,   0.1
5335     };
5336     float quad2[] = {
5337          0.0,   -1.0,   0.1,
5338          1.0,   -1.0,   0.1,
5339          0.0,    0.0,   0.1,
5340          1.0,    0.0,   0.1
5341     };
5342     float quad3[] = {
5343          0.0,    0.0,   0.1,
5344          1.0,    0.0,   0.1,
5345          0.0,    1.0,   0.1,
5346          1.0,    1.0,   0.1
5347     };
5348     float quad4[] = {
5349         -1.0,    0.0,   0.1,
5350          0.0,    0.0,   0.1,
5351         -1.0,    1.0,   0.1,
5352          0.0,    1.0,   0.1
5353     };
5354     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
5355     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
5356
5357     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5358     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5359
5360     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5361     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5362     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5363     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5364     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5365     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5366     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
5367     if(FAILED(hr)) shader_20 = NULL;
5368
5369     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5370     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5371     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5372     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5373     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5374     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5375
5376     hr = IDirect3DDevice9_BeginScene(device);
5377     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5378     if(SUCCEEDED(hr))
5379     {
5380         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5381         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5382         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5383         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5384
5385         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5386         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5387         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5388         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5389
5390         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5391         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5392         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5393         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5394
5395         if(shader_20) {
5396             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
5397             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5398             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5399             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5400         }
5401
5402         hr = IDirect3DDevice9_EndScene(device);
5403         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5404     }
5405     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5406     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5407
5408     color = getPixelColor(device, 160, 360);
5409     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5410        "quad 1 has color %08x, expected 0x00808000\n", color);
5411     color = getPixelColor(device, 480, 360);
5412     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5413        "quad 2 has color %08x, expected 0x00808000\n", color);
5414     color = getPixelColor(device, 480, 120);
5415     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5416        "quad 3 has color %08x, expected 0x00808000\n", color);
5417     if(shader_20) {
5418         color = getPixelColor(device, 160, 120);
5419         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5420            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5421     }
5422     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5423     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5424
5425     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5426     IDirect3DPixelShader9_Release(shader_14);
5427     IDirect3DPixelShader9_Release(shader_12);
5428     IDirect3DPixelShader9_Release(shader_11);
5429 }
5430
5431 static void dp2add_ps_test(IDirect3DDevice9 *device)
5432 {
5433     IDirect3DPixelShader9 *shader_dp2add = NULL;
5434     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5435     HRESULT hr;
5436     DWORD color;
5437
5438     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
5439      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5440      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
5441      * r0 first.
5442      * The result here for the r,g,b components should be roughly 0.5:
5443      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5444     static const DWORD shader_code_dp2add[] =  {
5445         0xffff0200,                                                             /* ps_2_0                       */
5446         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
5447
5448         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5449         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
5450
5451         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
5452         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5453         0x0000ffff                                                              /* end                          */
5454     };
5455
5456     /* Test the _sat modifier, too.  Result here should be:
5457      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5458      *      _SAT: ==> 1.0
5459      *   ADD: (1.0 + -0.5) = 0.5
5460      */
5461     static const DWORD shader_code_dp2add_sat[] =  {
5462         0xffff0200,                                                             /* ps_2_0                           */
5463         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
5464
5465         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
5466         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
5467         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5468
5469         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5470         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5471         0x0000ffff                                                              /* end                              */
5472     };
5473
5474     const float quad[] = {
5475         -1.0,   -1.0,   0.1,
5476          1.0,   -1.0,   0.1,
5477         -1.0,    1.0,   0.1,
5478          1.0,    1.0,   0.1
5479     };
5480
5481
5482     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5483     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5484
5485     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5486     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5487
5488     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5489     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5490
5491     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5492     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5493
5494     if (shader_dp2add) {
5495
5496         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5497         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5498
5499         hr = IDirect3DDevice9_BeginScene(device);
5500         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5501         if(SUCCEEDED(hr))
5502         {
5503             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5504             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5505
5506             hr = IDirect3DDevice9_EndScene(device);
5507             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5508         }
5509
5510         color = getPixelColor(device, 360, 240);
5511         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5512                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5513
5514         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5515         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5516
5517         IDirect3DPixelShader9_Release(shader_dp2add);
5518     } else {
5519         skip("dp2add shader creation failed\n");
5520     }
5521
5522     if (shader_dp2add_sat) {
5523
5524         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5525         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5526
5527         hr = IDirect3DDevice9_BeginScene(device);
5528         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5529         if(SUCCEEDED(hr))
5530         {
5531             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5532             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5533
5534             hr = IDirect3DDevice9_EndScene(device);
5535             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5536         }
5537
5538         color = getPixelColor(device, 360, 240);
5539         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5540                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5541
5542         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5543         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5544
5545         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5546     } else {
5547         skip("dp2add shader creation failed\n");
5548     }
5549
5550     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5551     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5552 }
5553
5554 static void cnd_test(IDirect3DDevice9 *device)
5555 {
5556     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5557     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5558     HRESULT hr;
5559     DWORD color;
5560     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5561      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5562      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5563      */
5564     DWORD shader_code_11[] =  {
5565         0xffff0101,                                                                 /* ps_1_1               */
5566         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5567         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5568         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5569         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5570         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5571         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5572         0x0000ffff                                                                  /* end                  */
5573     };
5574     DWORD shader_code_12[] =  {
5575         0xffff0102,                                                                 /* ps_1_2               */
5576         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5577         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5578         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5579         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5580         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5581         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5582         0x0000ffff                                                                  /* end                  */
5583     };
5584     DWORD shader_code_13[] =  {
5585         0xffff0103,                                                                 /* ps_1_3               */
5586         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5587         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5588         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5589         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5590         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5591         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5592         0x0000ffff                                                                  /* end                  */
5593     };
5594     DWORD shader_code_14[] =  {
5595         0xffff0104,                                                                 /* ps_1_3               */
5596         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5597         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5598         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5599         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5600         0x0000ffff                                                                  /* end                  */
5601     };
5602
5603     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5604      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5605      * set by the compiler, it was added manually after compilation. Note that the COISSUE
5606      * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5607      * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5608      * well enough.
5609      *
5610      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5611      * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5612      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5613      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5614      */
5615     DWORD shader_code_11_coissue[] =  {
5616         0xffff0101,                                                             /* ps_1_1                   */
5617         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5618         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5619         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5620         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5621         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5622         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5623         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5624         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5625         /* 0x40000000 = D3DSI_COISSUE */
5626         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5627         0x0000ffff                                                              /* end                      */
5628     };
5629     DWORD shader_code_12_coissue[] =  {
5630         0xffff0102,                                                             /* ps_1_2                   */
5631         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5632         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5633         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5634         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5635         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5636         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5637         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5638         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5639         /* 0x40000000 = D3DSI_COISSUE */
5640         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5641         0x0000ffff                                                              /* end                      */
5642     };
5643     DWORD shader_code_13_coissue[] =  {
5644         0xffff0103,                                                             /* ps_1_3                   */
5645         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5646         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5647         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5648         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5649         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5650         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5651         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5652         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5653         /* 0x40000000 = D3DSI_COISSUE */
5654         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5655         0x0000ffff                                                              /* end                      */
5656     };
5657     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5658      * compare against 0.5
5659      */
5660     DWORD shader_code_14_coissue[] =  {
5661         0xffff0104,                                                             /* ps_1_4                   */
5662         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5663         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5664         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5665         /* 0x40000000 = D3DSI_COISSUE */
5666         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5667         0x0000ffff                                                              /* end                      */
5668     };
5669     float quad1[] = {
5670         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5671          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5672         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5673          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5674     };
5675     float quad2[] = {
5676          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5677          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5678          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5679          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5680     };
5681     float quad3[] = {
5682          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5683          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5684          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5685          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5686     };
5687     float quad4[] = {
5688         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5689          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5690         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5691          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5692     };
5693     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5694     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5695     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5696     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5697
5698     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5699     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5700
5701     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5702     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5703     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5704     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5705     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5706     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5707     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5708     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5709     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5710     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5711     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5712     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5713     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5714     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5715     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5716     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5717
5718     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5719     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5720     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5721     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5722     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5723     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5724
5725     hr = IDirect3DDevice9_BeginScene(device);
5726     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5727     if(SUCCEEDED(hr))
5728     {
5729         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5730         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5731         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5732         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5733
5734         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5735         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5736         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5737         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5738
5739         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5740         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5741         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5742         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5743
5744         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5745         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5746         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5747         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5748
5749         hr = IDirect3DDevice9_EndScene(device);
5750         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5751     }
5752
5753     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5754     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5755
5756     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5757     color = getPixelColor(device, 158, 118);
5758     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5759     color = getPixelColor(device, 162, 118);
5760     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5761     color = getPixelColor(device, 158, 122);
5762     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5763     color = getPixelColor(device, 162, 122);
5764     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5765
5766     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5767     color = getPixelColor(device, 158, 358);
5768     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5769     color = getPixelColor(device, 162, 358);
5770     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5771         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5772     color = getPixelColor(device, 158, 362);
5773     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5774     color = getPixelColor(device, 162, 362);
5775     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5776         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5777
5778     /* 1.2 shader */
5779     color = getPixelColor(device, 478, 358);
5780     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5781     color = getPixelColor(device, 482, 358);
5782     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5783         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5784     color = getPixelColor(device, 478, 362);
5785     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5786     color = getPixelColor(device, 482, 362);
5787     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5788         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5789
5790     /* 1.3 shader */
5791     color = getPixelColor(device, 478, 118);
5792     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5793     color = getPixelColor(device, 482, 118);
5794     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5795         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5796     color = getPixelColor(device, 478, 122);
5797     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5798     color = getPixelColor(device, 482, 122);
5799     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5800         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5801
5802     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5803     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5804
5805     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5806     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5807     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5808     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5809     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5810     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5811
5812     hr = IDirect3DDevice9_BeginScene(device);
5813     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5814     if(SUCCEEDED(hr))
5815     {
5816         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5817         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5818         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5819         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5820
5821         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5822         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5823         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5824         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5825
5826         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5827         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5828         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5829         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5830
5831         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5832         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5833         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5834         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5835
5836         hr = IDirect3DDevice9_EndScene(device);
5837         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5838     }
5839
5840     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5841     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5842
5843     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5844      * that we swapped the values in c1 and c2 to make the other tests return some color
5845      */
5846     color = getPixelColor(device, 158, 118);
5847     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5848     color = getPixelColor(device, 162, 118);
5849     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5850     color = getPixelColor(device, 158, 122);
5851     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5852     color = getPixelColor(device, 162, 122);
5853     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5854
5855     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5856      * (The Win7 nvidia driver always selects c2)
5857      */
5858     color = getPixelColor(device, 158, 358);
5859     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5860         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5861     color = getPixelColor(device, 162, 358);
5862     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5863         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5864     color = getPixelColor(device, 158, 362);
5865     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5866         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5867     color = getPixelColor(device, 162, 362);
5868     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5869         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5870
5871     /* 1.2 shader */
5872     color = getPixelColor(device, 478, 358);
5873     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5874         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5875     color = getPixelColor(device, 482, 358);
5876     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5877         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5878     color = getPixelColor(device, 478, 362);
5879     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5880         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5881     color = getPixelColor(device, 482, 362);
5882     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5883         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5884
5885     /* 1.3 shader */
5886     color = getPixelColor(device, 478, 118);
5887     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5888         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5889     color = getPixelColor(device, 482, 118);
5890     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5891         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5892     color = getPixelColor(device, 478, 122);
5893     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5894         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5895     color = getPixelColor(device, 482, 122);
5896     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5897         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5898
5899     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5900     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5901
5902     IDirect3DPixelShader9_Release(shader_14_coissue);
5903     IDirect3DPixelShader9_Release(shader_13_coissue);
5904     IDirect3DPixelShader9_Release(shader_12_coissue);
5905     IDirect3DPixelShader9_Release(shader_11_coissue);
5906     IDirect3DPixelShader9_Release(shader_14);
5907     IDirect3DPixelShader9_Release(shader_13);
5908     IDirect3DPixelShader9_Release(shader_12);
5909     IDirect3DPixelShader9_Release(shader_11);
5910 }
5911
5912 static void nested_loop_test(IDirect3DDevice9 *device) {
5913     const DWORD shader_code[] = {
5914         0xffff0300,                                                             /* ps_3_0               */
5915         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5916         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5917         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5918         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5919         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5920         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5921         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5922         0x0000001d,                                                             /* endloop              */
5923         0x0000001d,                                                             /* endloop              */
5924         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5925         0x0000ffff                                                              /* end                  */
5926     };
5927     const DWORD vshader_code[] = {
5928         0xfffe0300,                                                             /* vs_3_0               */
5929         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
5930         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
5931         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
5932         0x0000ffff                                                              /* end                  */
5933     };
5934     IDirect3DPixelShader9 *shader;
5935     IDirect3DVertexShader9 *vshader;
5936     HRESULT hr;
5937     DWORD color;
5938     const float quad[] = {
5939         -1.0,   -1.0,   0.1,
5940          1.0,   -1.0,   0.1,
5941         -1.0,    1.0,   0.1,
5942          1.0,    1.0,   0.1
5943     };
5944
5945     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5946     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5947     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5948     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5949     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5950     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5951     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5952     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5953     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5954     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5955     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5956     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5957
5958     hr = IDirect3DDevice9_BeginScene(device);
5959     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5960     if(SUCCEEDED(hr))
5961     {
5962         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5963         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5964         hr = IDirect3DDevice9_EndScene(device);
5965         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5966     }
5967
5968     color = getPixelColor(device, 360, 240);
5969     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5970        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5971
5972     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5973     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5974
5975     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5976     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5977     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5978     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5979     IDirect3DPixelShader9_Release(shader);
5980     IDirect3DVertexShader9_Release(vshader);
5981 }
5982
5983 struct varying_test_struct
5984 {
5985     const DWORD             *shader_code;
5986     IDirect3DPixelShader9   *shader;
5987     DWORD                   color, color_rhw;
5988     const char              *name;
5989     BOOL                    todo, todo_rhw;
5990 };
5991
5992 struct hugeVertex
5993 {
5994     float pos_x,        pos_y,      pos_z,      rhw;
5995     float weight_1,     weight_2,   weight_3,   weight_4;
5996     float index_1,      index_2,    index_3,    index_4;
5997     float normal_1,     normal_2,   normal_3,   normal_4;
5998     float fog_1,        fog_2,      fog_3,      fog_4;
5999     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
6000     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
6001     float binormal_1,   binormal_2, binormal_3, binormal_4;
6002     float depth_1,      depth_2,    depth_3,    depth_4;
6003     DWORD diffuse, specular;
6004 };
6005
6006 static void pretransformed_varying_test(IDirect3DDevice9 *device) {
6007     /* dcl_position: fails to compile */
6008     const DWORD blendweight_code[] = {
6009         0xffff0300,                             /* ps_3_0                   */
6010         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
6011         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6012         0x0000ffff                              /* end                      */
6013     };
6014     const DWORD blendindices_code[] = {
6015         0xffff0300,                             /* ps_3_0                   */
6016         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
6017         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6018         0x0000ffff                              /* end                      */
6019     };
6020     const DWORD normal_code[] = {
6021         0xffff0300,                             /* ps_3_0                   */
6022         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
6023         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6024         0x0000ffff                              /* end                      */
6025     };
6026     /* psize: fails? */
6027     const DWORD texcoord0_code[] = {
6028         0xffff0300,                             /* ps_3_0                   */
6029         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
6030         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6031         0x0000ffff                              /* end                      */
6032     };
6033     const DWORD tangent_code[] = {
6034         0xffff0300,                             /* ps_3_0                   */
6035         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
6036         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6037         0x0000ffff                              /* end                      */
6038     };
6039     const DWORD binormal_code[] = {
6040         0xffff0300,                             /* ps_3_0                   */
6041         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
6042         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6043         0x0000ffff                              /* end                      */
6044     };
6045     /* tessfactor: fails */
6046     /* positiont: fails */
6047     const DWORD color_code[] = {
6048         0xffff0300,                             /* ps_3_0                   */
6049         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
6050         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6051         0x0000ffff                              /* end                      */
6052     };
6053     const DWORD fog_code[] = {
6054         0xffff0300,                             /* ps_3_0                   */
6055         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
6056         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6057         0x0000ffff                              /* end                      */
6058     };
6059     const DWORD depth_code[] = {
6060         0xffff0300,                             /* ps_3_0                   */
6061         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
6062         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6063         0x0000ffff                              /* end                      */
6064     };
6065     const DWORD specular_code[] = {
6066         0xffff0300,                             /* ps_3_0                   */
6067         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
6068         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6069         0x0000ffff                              /* end                      */
6070     };
6071     /* sample: fails */
6072
6073     struct varying_test_struct tests[] = {
6074        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
6075        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
6076        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
6077        /* Why does dx not forward the texcoord? */
6078        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
6079        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
6080        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
6081        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
6082        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
6083        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
6084        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
6085     };
6086     /* Declare a monster vertex type :-) */
6087     static const D3DVERTEXELEMENT9 decl_elements[] = {
6088         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6089         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
6090         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
6091         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
6092         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
6093         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6094         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
6095         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
6096         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
6097         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6098         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
6099         D3DDECL_END()
6100     };
6101     struct hugeVertex data[4] = {
6102         {
6103             -1.0,   -1.0,   0.1,    1.0,
6104              0.1,    0.1,   0.1,    0.1,
6105              0.2,    0.2,   0.2,    0.2,
6106              0.3,    0.3,   0.3,    0.3,
6107              0.4,    0.4,   0.4,    0.4,
6108              0.50,   0.55,  0.55,   0.55,
6109              0.6,    0.6,   0.6,    0.7,
6110              0.7,    0.7,   0.7,    0.6,
6111              0.8,    0.8,   0.8,    0.8,
6112              0xe6e6e6e6, /* 0.9 * 256 */
6113              0x224488ff  /* Nothing special */
6114         },
6115         {
6116              1.0,   -1.0,   0.1,    1.0,
6117              0.1,    0.1,   0.1,    0.1,
6118              0.2,    0.2,   0.2,    0.2,
6119              0.3,    0.3,   0.3,    0.3,
6120              0.4,    0.4,   0.4,    0.4,
6121              0.50,   0.55,  0.55,   0.55,
6122              0.6,    0.6,   0.6,    0.7,
6123              0.7,    0.7,   0.7,    0.6,
6124              0.8,    0.8,   0.8,    0.8,
6125              0xe6e6e6e6, /* 0.9 * 256 */
6126              0x224488ff /* Nothing special */
6127         },
6128         {
6129             -1.0,    1.0,   0.1,    1.0,
6130              0.1,    0.1,   0.1,    0.1,
6131              0.2,    0.2,   0.2,    0.2,
6132              0.3,    0.3,   0.3,    0.3,
6133              0.4,    0.4,   0.4,    0.4,
6134              0.50,   0.55,  0.55,   0.55,
6135              0.6,    0.6,   0.6,    0.7,
6136              0.7,    0.7,   0.7,    0.6,
6137              0.8,    0.8,   0.8,    0.8,
6138              0xe6e6e6e6, /* 0.9 * 256 */
6139              0x224488ff /* Nothing special */
6140         },
6141         {
6142              1.0,    1.0,   0.1,    1.0,
6143              0.1,    0.1,   0.1,    0.1,
6144              0.2,    0.2,   0.2,    0.2,
6145              0.3,    0.3,   0.3,    0.3,
6146              0.4,    0.4,   0.4,    0.4,
6147              0.50,   0.55,  0.55,   0.55,
6148              0.6,    0.6,   0.6,    0.7,
6149              0.7,    0.7,   0.7,    0.6,
6150              0.8,    0.8,   0.8,    0.8,
6151              0xe6e6e6e6, /* 0.9 * 256 */
6152              0x224488ff /* Nothing special */
6153         },
6154     };
6155     struct hugeVertex data2[4];
6156     IDirect3DVertexDeclaration9 *decl;
6157     HRESULT hr;
6158     unsigned int i;
6159     DWORD color, r, g, b, r_e, g_e, b_e;
6160
6161     memcpy(data2, data, sizeof(data2));
6162     data2[0].pos_x = 0;     data2[0].pos_y = 0;
6163     data2[1].pos_x = 640;   data2[1].pos_y = 0;
6164     data2[2].pos_x = 0;     data2[2].pos_y = 480;
6165     data2[3].pos_x = 640;   data2[3].pos_y = 480;
6166
6167     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6168     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6169     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6170     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6171
6172     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6173     {
6174         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
6175         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
6176            tests[i].name, hr);
6177     }
6178
6179     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6180     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6181     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6182     {
6183         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6184         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6185
6186         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
6187         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6188
6189         hr = IDirect3DDevice9_BeginScene(device);
6190         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6191         if(SUCCEEDED(hr))
6192         {
6193             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
6194             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6195             hr = IDirect3DDevice9_EndScene(device);
6196             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6197         }
6198
6199         color = getPixelColor(device, 360, 240);
6200         r = color & 0x00ff0000 >> 16;
6201         g = color & 0x0000ff00 >>  8;
6202         b = color & 0x000000ff;
6203         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
6204         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
6205         b_e = tests[i].color_rhw & 0x000000ff;
6206
6207         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6208         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6209
6210         if(tests[i].todo_rhw) {
6211             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
6212              * pipeline
6213              */
6214             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6215                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
6216                          tests[i].name, color, tests[i].color_rhw);
6217         } else {
6218             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6219                "Test %s returned color 0x%08x, expected 0x%08x\n",
6220                tests[i].name, color, tests[i].color_rhw);
6221         }
6222     }
6223
6224     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6225     {
6226         IDirect3DPixelShader9_Release(tests[i].shader);
6227     }
6228
6229     IDirect3DVertexDeclaration9_Release(decl);
6230 }
6231
6232 static void test_compare_instructions(IDirect3DDevice9 *device)
6233 {
6234     DWORD shader_sge_vec_code[] = {
6235         0xfffe0101,                                         /* vs_1_1                   */
6236         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6237         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6238         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6239         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
6240         0x0000ffff                                          /* end                      */
6241     };
6242     DWORD shader_slt_vec_code[] = {
6243         0xfffe0101,                                         /* vs_1_1                   */
6244         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6245         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6246         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6247         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
6248         0x0000ffff                                          /* end                      */
6249     };
6250     DWORD shader_sge_scalar_code[] = {
6251         0xfffe0101,                                         /* vs_1_1                   */
6252         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6253         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6254         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6255         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
6256         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
6257         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
6258         0x0000ffff                                          /* end                      */
6259     };
6260     DWORD shader_slt_scalar_code[] = {
6261         0xfffe0101,                                         /* vs_1_1                   */
6262         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6263         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6264         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6265         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
6266         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
6267         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
6268         0x0000ffff                                          /* end                      */
6269     };
6270     IDirect3DVertexShader9 *shader_sge_vec;
6271     IDirect3DVertexShader9 *shader_slt_vec;
6272     IDirect3DVertexShader9 *shader_sge_scalar;
6273     IDirect3DVertexShader9 *shader_slt_scalar;
6274     HRESULT hr, color;
6275     float quad1[] =  {
6276         -1.0,   -1.0,   0.1,
6277          0.0,   -1.0,   0.1,
6278         -1.0,    0.0,   0.1,
6279          0.0,    0.0,   0.1
6280     };
6281     float quad2[] =  {
6282          0.0,   -1.0,   0.1,
6283          1.0,   -1.0,   0.1,
6284          0.0,    0.0,   0.1,
6285          1.0,    0.0,   0.1
6286     };
6287     float quad3[] =  {
6288         -1.0,    0.0,   0.1,
6289          0.0,    0.0,   0.1,
6290         -1.0,    1.0,   0.1,
6291          0.0,    1.0,   0.1
6292     };
6293     float quad4[] =  {
6294          0.0,    0.0,   0.1,
6295          1.0,    0.0,   0.1,
6296          0.0,    1.0,   0.1,
6297          1.0,    1.0,   0.1
6298     };
6299     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6300     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6301
6302     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6303     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6304
6305     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6306     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6307     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6308     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6309     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6310     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6311     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6312     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6313     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6314     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6315     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6316     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6317     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6318     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6319
6320     hr = IDirect3DDevice9_BeginScene(device);
6321     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6322     if(SUCCEEDED(hr))
6323     {
6324         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6325         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6326         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6327         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6328
6329         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6330         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6331         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6332         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6333
6334         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6335         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6336         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6337         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6338
6339         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6340         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6341
6342         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6343         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6344         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6345         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6346
6347         hr = IDirect3DDevice9_EndScene(device);
6348         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6349     }
6350
6351     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6352     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6353
6354     color = getPixelColor(device, 160, 360);
6355     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6356     color = getPixelColor(device, 480, 360);
6357     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6358     color = getPixelColor(device, 160, 120);
6359     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6360     color = getPixelColor(device, 480, 160);
6361     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6362
6363     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6364     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6365
6366     IDirect3DVertexShader9_Release(shader_sge_vec);
6367     IDirect3DVertexShader9_Release(shader_slt_vec);
6368     IDirect3DVertexShader9_Release(shader_sge_scalar);
6369     IDirect3DVertexShader9_Release(shader_slt_scalar);
6370 }
6371
6372 static void test_vshader_input(IDirect3DDevice9 *device)
6373 {
6374     static const DWORD swapped_shader_code_3[] =
6375     {
6376         0xfffe0300,                                         /* vs_3_0               */
6377         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6378         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6379         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6380         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6381         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6382         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6383         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6384         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6385         0x0000ffff                                          /* end                  */
6386     };
6387     static const DWORD swapped_shader_code_1[] =
6388     {
6389         0xfffe0101,                                         /* vs_1_1               */
6390         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6391         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6392         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6393         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6394         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6395         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6396         0x0000ffff                                          /* end                  */
6397     };
6398     static const DWORD swapped_shader_code_2[] =
6399     {
6400         0xfffe0200,                                         /* vs_2_0               */
6401         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6402         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6403         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6404         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6405         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6406         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6407         0x0000ffff                                          /* end                  */
6408     };
6409     static const DWORD texcoord_color_shader_code_3[] =
6410     {
6411         0xfffe0300,                                         /* vs_3_0               */
6412         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6413         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6414         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6415         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6416         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6417         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6418         0x0000ffff                                          /* end                  */
6419     };
6420     static const DWORD texcoord_color_shader_code_2[] =
6421     {
6422         0xfffe0200,                                         /* vs_2_0               */
6423         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6424         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6425         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6426         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6427         0x0000ffff                                          /* end                  */
6428     };
6429     static const DWORD texcoord_color_shader_code_1[] =
6430     {
6431         0xfffe0101,                                         /* vs_1_1               */
6432         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6433         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6434         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6435         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6436         0x0000ffff                                          /* end                  */
6437     };
6438     static const DWORD color_color_shader_code_3[] =
6439     {
6440         0xfffe0300,                                         /* vs_3_0               */
6441         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6442         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6443         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6444         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6445         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6446         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6447         0x0000ffff                                          /* end                  */
6448     };
6449     static const DWORD color_color_shader_code_2[] =
6450     {
6451         0xfffe0200,                                         /* vs_2_0               */
6452         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6453         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6454         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6455         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6456         0x0000ffff                                          /* end                  */
6457     };
6458     static const DWORD color_color_shader_code_1[] =
6459     {
6460         0xfffe0101,                                         /* vs_1_1               */
6461         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6462         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6463         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6464         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6465         0x0000ffff                                          /* end                  */
6466     };
6467     static const DWORD ps3_code[] =
6468     {
6469         0xffff0300,                                         /* ps_3_0               */
6470         0x0200001f, 0x8000000a, 0x900f0000,                 /* dcl_color0 v0        */
6471         0x02000001, 0x800f0800, 0x90e40000,                 /* mov oC0, v0          */
6472         0x0000ffff                                          /* end                  */
6473     };
6474     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6475     IDirect3DPixelShader9 *ps;
6476     HRESULT hr;
6477     DWORD color;
6478     float quad1[] =  {
6479         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6480          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6481         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6482          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6483     };
6484     float quad2[] =  {
6485          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6486          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6487          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6488          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6489     };
6490     float quad3[] =  {
6491         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6492          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6493         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6494          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6495     };
6496     float quad4[] =  {
6497          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6498          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6499          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6500          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6501     };
6502     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6503         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6504         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6505         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6506         D3DDECL_END()
6507     };
6508     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6509         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6510         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6511         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6512         D3DDECL_END()
6513     };
6514     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6515         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6516         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6517         D3DDECL_END()
6518     };
6519     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6520         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6521         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6522         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6523         D3DDECL_END()
6524     };
6525     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6526         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6527         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6528         D3DDECL_END()
6529     };
6530     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6531         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6532         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6533         D3DDECL_END()
6534     };
6535     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6536         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6537         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6538         D3DDECL_END()
6539     };
6540     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6541         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6542         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6543         D3DDECL_END()
6544     };
6545     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6546     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6547     unsigned int i;
6548     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6549     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6550
6551     struct vertex quad1_color[] =  {
6552        {-1.0,   -1.0,   0.1,    0x00ff8040},
6553        { 0.0,   -1.0,   0.1,    0x00ff8040},
6554        {-1.0,    0.0,   0.1,    0x00ff8040},
6555        { 0.0,    0.0,   0.1,    0x00ff8040}
6556     };
6557     struct vertex quad2_color[] =  {
6558        { 0.0,   -1.0,   0.1,    0x00ff8040},
6559        { 1.0,   -1.0,   0.1,    0x00ff8040},
6560        { 0.0,    0.0,   0.1,    0x00ff8040},
6561        { 1.0,    0.0,   0.1,    0x00ff8040}
6562     };
6563     struct vertex quad3_color[] =  {
6564        {-1.0,    0.0,   0.1,    0x00ff8040},
6565        { 0.0,    0.0,   0.1,    0x00ff8040},
6566        {-1.0,    1.0,   0.1,    0x00ff8040},
6567        { 0.0,    1.0,   0.1,    0x00ff8040}
6568     };
6569     float quad4_color[] =  {
6570          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6571          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6572          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6573          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6574     };
6575
6576     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6577     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6578     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6579     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6580     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6581     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6582     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6583     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6584
6585     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6586     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6587     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6588     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6589     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6590     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6591     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6592     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6593
6594     hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
6595     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6596
6597     for(i = 1; i <= 3; i++) {
6598         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6599         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6600         if(i == 3) {
6601             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6602             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6603             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6604             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6605         } else if(i == 2){
6606             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6607             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6608         } else if(i == 1) {
6609             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6610             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6611         }
6612
6613         hr = IDirect3DDevice9_BeginScene(device);
6614         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6615         if(SUCCEEDED(hr))
6616         {
6617             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6618             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6619
6620             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6621             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6622             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6623             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6624
6625             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6626             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6627             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6628             if(i == 3 || i == 2) {
6629                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6630             } else if(i == 1) {
6631                 /* Succeeds or fails, depending on SW or HW vertex processing */
6632                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6633             }
6634
6635             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6636             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6637             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6638             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6639
6640             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6641             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6642             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6643             if(i == 3 || i == 2) {
6644                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6645             } else if(i == 1) {
6646                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6647             }
6648
6649             hr = IDirect3DDevice9_EndScene(device);
6650             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6651         }
6652
6653         if(i == 3 || i == 2) {
6654             color = getPixelColor(device, 160, 360);
6655             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6656                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6657
6658             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6659             color = getPixelColor(device, 480, 360);
6660             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6661                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6662             color = getPixelColor(device, 160, 120);
6663             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6664             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6665                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6666
6667             color = getPixelColor(device, 480, 160);
6668             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6669         } else if(i == 1) {
6670             color = getPixelColor(device, 160, 360);
6671             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6672                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6673             color = getPixelColor(device, 480, 360);
6674             /* Accept the clear color as well in this case, since SW VP returns an error */
6675             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6676             color = getPixelColor(device, 160, 120);
6677             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6678                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6679             color = getPixelColor(device, 480, 160);
6680             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6681         }
6682
6683         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6684         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6685
6686         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6687         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6688
6689         /* Now find out if the whole streams are re-read, or just the last active value for the
6690          * vertices is used.
6691          */
6692         hr = IDirect3DDevice9_BeginScene(device);
6693         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6694         if(SUCCEEDED(hr))
6695         {
6696             float quad1_modified[] =  {
6697                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6698                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6699                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6700                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6701             };
6702             float quad2_modified[] =  {
6703                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6704                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6705                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6706                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6707             };
6708
6709             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6710             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6711
6712             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6713             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6714             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6715             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6716
6717             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6718             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6719             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6720             if(i == 3 || i == 2) {
6721                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6722             } else if(i == 1) {
6723                 /* Succeeds or fails, depending on SW or HW vertex processing */
6724                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6725             }
6726
6727             hr = IDirect3DDevice9_EndScene(device);
6728             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6729         }
6730
6731         color = getPixelColor(device, 480, 350);
6732         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6733          * as well.
6734          *
6735          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6736          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6737          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6738          * refrast's result.
6739          *
6740          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6741          */
6742         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6743            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6744
6745         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6746         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6747
6748         IDirect3DDevice9_SetVertexShader(device, NULL);
6749         IDirect3DDevice9_SetPixelShader(device, NULL);
6750         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6751
6752         IDirect3DVertexShader9_Release(swapped_shader);
6753     }
6754
6755     for(i = 1; i <= 3; i++) {
6756         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6757         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6758         if(i == 3) {
6759             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6760             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6761             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6762             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6763             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6764             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6765         } else if(i == 2){
6766             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6767             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6768             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6769             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6770         } else if(i == 1) {
6771             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6772             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6773             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6774             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6775         }
6776
6777         hr = IDirect3DDevice9_BeginScene(device);
6778         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6779         if(SUCCEEDED(hr))
6780         {
6781             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6782             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6783             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6784             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6785             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6786             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6787
6788             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6789             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6790
6791             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6792             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6793             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6794             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6795             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6796             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6797
6798             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6799             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6800             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6801             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6802             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6803             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6804
6805             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6806             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6807             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6808             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6809
6810             hr = IDirect3DDevice9_EndScene(device);
6811             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6812         }
6813         IDirect3DDevice9_SetVertexShader(device, NULL);
6814         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6815         IDirect3DDevice9_SetPixelShader(device, NULL);
6816
6817         color = getPixelColor(device, 160, 360);
6818         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6819            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6820         color = getPixelColor(device, 480, 360);
6821         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6822            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6823         color = getPixelColor(device, 160, 120);
6824         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6825            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6826         color = getPixelColor(device, 480, 160);
6827         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6828            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6829
6830         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6831         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6832
6833         IDirect3DVertexShader9_Release(texcoord_color_shader);
6834         IDirect3DVertexShader9_Release(color_color_shader);
6835     }
6836
6837     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6838     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6839     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6840     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6841
6842     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6843     IDirect3DVertexDeclaration9_Release(decl_color_color);
6844     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6845     IDirect3DVertexDeclaration9_Release(decl_color_float);
6846
6847     IDirect3DPixelShader9_Release(ps);
6848 }
6849
6850 static void srgbtexture_test(IDirect3DDevice9 *device)
6851 {
6852     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6853      * texture stage state to render a quad using that texture.  The resulting
6854      * color components should be 0x36 (~ 0.21), per this formula:
6855      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6856      * This is true where srgb_color > 0.04045.
6857      */
6858     IDirect3D9 *d3d = NULL;
6859     HRESULT hr;
6860     LPDIRECT3DTEXTURE9 texture = NULL;
6861     LPDIRECT3DSURFACE9 surface = NULL;
6862     D3DLOCKED_RECT lr;
6863     DWORD color;
6864     float quad[] = {
6865         -1.0,       1.0,       0.0,     0.0,    0.0,
6866          1.0,       1.0,       0.0,     1.0,    0.0,
6867         -1.0,      -1.0,       0.0,     0.0,    1.0,
6868          1.0,      -1.0,       0.0,     1.0,    1.0,
6869     };
6870
6871
6872     memset(&lr, 0, sizeof(lr));
6873     IDirect3DDevice9_GetDirect3D(device, &d3d);
6874     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6875                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6876                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6877         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6878         goto out;
6879     }
6880
6881     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6882                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6883                                         &texture, NULL);
6884     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6885     if(!texture) {
6886         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6887         goto out;
6888     }
6889     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6890     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6891
6892     fill_surface(surface, 0xff7f7f7f);
6893     IDirect3DSurface9_Release(surface);
6894
6895     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6896     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6897     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6898     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6899
6900     hr = IDirect3DDevice9_BeginScene(device);
6901     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6902     if(SUCCEEDED(hr))
6903     {
6904         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6905         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6906
6907         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6908         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6909
6910
6911         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6912         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6913
6914         hr = IDirect3DDevice9_EndScene(device);
6915         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6916     }
6917
6918     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6919     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6920     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6921     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6922
6923     color = getPixelColor(device, 320, 240);
6924     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6925
6926     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6927     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6928
6929 out:
6930     if(texture) IDirect3DTexture9_Release(texture);
6931     IDirect3D9_Release(d3d);
6932 }
6933
6934 static void shademode_test(IDirect3DDevice9 *device)
6935 {
6936     /* Render a quad and try all of the different fixed function shading models. */
6937     HRESULT hr;
6938     DWORD color0, color1;
6939     DWORD color0_gouraud = 0, color1_gouraud = 0;
6940     DWORD shademode = D3DSHADE_FLAT;
6941     DWORD primtype = D3DPT_TRIANGLESTRIP;
6942     LPVOID data = NULL;
6943     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6944     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6945     UINT i, j;
6946     struct vertex quad_strip[] =
6947     {
6948         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6949         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6950         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6951         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6952     };
6953     struct vertex quad_list[] =
6954     {
6955         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6956         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6957         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6958
6959         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6960         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6961         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6962     };
6963
6964     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6965                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6966     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6967     if (FAILED(hr)) goto bail;
6968
6969     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6970                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6971     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6972     if (FAILED(hr)) goto bail;
6973
6974     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6975     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6976
6977     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6978     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6979
6980     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6981     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6982     memcpy(data, quad_strip, sizeof(quad_strip));
6983     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6984     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6985
6986     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6987     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6988     memcpy(data, quad_list, sizeof(quad_list));
6989     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6990     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6991
6992     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6993      * the color fixups we have to do for FLAT shading will be dependent on that. */
6994     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6995     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6996
6997     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6998     for (j=0; j<2; j++) {
6999
7000         /* Inner loop just changes the D3DRS_SHADEMODE */
7001         for (i=0; i<3; i++) {
7002             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7003             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7004
7005             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
7006             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7007
7008             hr = IDirect3DDevice9_BeginScene(device);
7009             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7010             if(SUCCEEDED(hr))
7011             {
7012                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
7013                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
7014
7015                 hr = IDirect3DDevice9_EndScene(device);
7016                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7017             }
7018
7019             /* Sample two spots from the output */
7020             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
7021             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
7022             switch(shademode) {
7023                 case D3DSHADE_FLAT:
7024                     /* Should take the color of the first vertex of each triangle */
7025                     if (0)
7026                     {
7027                         /* This test depends on EXT_provoking_vertex being
7028                          * available. This extension is currently (20090810)
7029                          * not common enough to let the test fail if it isn't
7030                          * present. */
7031                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
7032                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
7033                     }
7034                     shademode = D3DSHADE_GOURAUD;
7035                     break;
7036                 case D3DSHADE_GOURAUD:
7037                     /* Should be an interpolated blend */
7038
7039                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7040                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
7041                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7042                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
7043
7044                     color0_gouraud = color0;
7045                     color1_gouraud = color1;
7046
7047                     shademode = D3DSHADE_PHONG;
7048                     break;
7049                 case D3DSHADE_PHONG:
7050                     /* Should be the same as GOURAUD, since no hardware implements this */
7051                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7052                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
7053                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7054                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7055
7056                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7057                             color0_gouraud, color0);
7058                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7059                             color1_gouraud, color1);
7060                     break;
7061             }
7062         }
7063
7064         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7065         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7066
7067         /* Now, do it all over again with a TRIANGLELIST */
7068         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7069         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7070         primtype = D3DPT_TRIANGLELIST;
7071         shademode = D3DSHADE_FLAT;
7072     }
7073
7074 bail:
7075     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7076     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7077     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7078     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7079
7080     if (vb_strip)
7081         IDirect3DVertexBuffer9_Release(vb_strip);
7082     if (vb_list)
7083         IDirect3DVertexBuffer9_Release(vb_list);
7084 }
7085
7086 static void alpha_test(IDirect3DDevice9 *device)
7087 {
7088     HRESULT hr;
7089     IDirect3DTexture9 *offscreenTexture;
7090     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7091     DWORD color;
7092
7093     struct vertex quad1[] =
7094     {
7095         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
7096         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
7097         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
7098         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
7099     };
7100     struct vertex quad2[] =
7101     {
7102         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
7103         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
7104         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
7105         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
7106     };
7107     static const float composite_quad[][5] = {
7108         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7109         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
7110         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7111         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
7112     };
7113
7114     /* Clear the render target with alpha = 0.5 */
7115     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7116     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7117
7118     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7119     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7120
7121     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7122     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7123     if(!backbuffer) {
7124         goto out;
7125     }
7126
7127     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7128     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7129     if(!offscreen) {
7130         goto out;
7131     }
7132
7133     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7134     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7135
7136     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7137     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7138     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7139     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7140     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7141     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7142     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7143     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7144     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7145     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7146
7147     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7148     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7149     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7150
7151         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7152         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7153         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7154         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7155         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7156         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7157         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7158
7159         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7160         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7161         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7162         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7163         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7164         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7165
7166         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7167          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7168          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7169         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7170         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7171         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7172         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7173
7174         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7175         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7176         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7177         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7178         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7179         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7180
7181         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7182         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7183         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7184         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7185         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7186         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7187
7188         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7189         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7190
7191         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7192          * Disable alpha blending for the final composition
7193          */
7194         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7195         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7196         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7197         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7198
7199         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7200         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7201         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7202         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7203         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7204         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7205
7206         hr = IDirect3DDevice9_EndScene(device);
7207         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7208     }
7209
7210     color = getPixelColor(device, 160, 360);
7211     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7212        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7213
7214     color = getPixelColor(device, 160, 120);
7215     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7216        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7217
7218     color = getPixelColor(device, 480, 360);
7219     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7220        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7221
7222     color = getPixelColor(device, 480, 120);
7223     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7224        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7225
7226     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7227
7228     out:
7229     /* restore things */
7230     if(backbuffer) {
7231         IDirect3DSurface9_Release(backbuffer);
7232     }
7233     if(offscreenTexture) {
7234         IDirect3DTexture9_Release(offscreenTexture);
7235     }
7236     if(offscreen) {
7237         IDirect3DSurface9_Release(offscreen);
7238     }
7239 }
7240
7241 struct vertex_shortcolor {
7242     float x, y, z;
7243     unsigned short r, g, b, a;
7244 };
7245 struct vertex_floatcolor {
7246     float x, y, z;
7247     float r, g, b, a;
7248 };
7249
7250 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7251 {
7252     HRESULT hr;
7253     BOOL s_ok, ub_ok, f_ok;
7254     DWORD color, size, i;
7255     void *data;
7256     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7257         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7258         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7259         D3DDECL_END()
7260     };
7261     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7262         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7263         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7264         D3DDECL_END()
7265     };
7266     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7267         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7268         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7269         D3DDECL_END()
7270     };
7271     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7272         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7273         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7274         D3DDECL_END()
7275     };
7276     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7277         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7278         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7279         D3DDECL_END()
7280     };
7281     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7282         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7283         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7284         D3DDECL_END()
7285     };
7286     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7287         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
7288         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7289         D3DDECL_END()
7290     };
7291     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7292     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7293     IDirect3DVertexBuffer9 *vb, *vb2;
7294     struct vertex quad1[] =                             /* D3DCOLOR */
7295     {
7296         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
7297         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7298         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
7299         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7300     };
7301     struct vertex quad2[] =                             /* UBYTE4N */
7302     {
7303         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7304         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
7305         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7306         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
7307     };
7308     struct vertex_shortcolor quad3[] =                  /* short */
7309     {
7310         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7311         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7312         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7313         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7314     };
7315     struct vertex_floatcolor quad4[] =
7316     {
7317         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7318         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7319         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7320         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7321     };
7322     DWORD colors[] = {
7323         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7324         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7325         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7326         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7327         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7328         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7329         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7330         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7331         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7332         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7333         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7334         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7335         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7336         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7337         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7338         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7339     };
7340     float quads[] = {
7341         -1.0,   -1.0,     0.1,
7342         -1.0,    0.0,     0.1,
7343          0.0,   -1.0,     0.1,
7344          0.0,    0.0,     0.1,
7345
7346          0.0,   -1.0,     0.1,
7347          0.0,    0.0,     0.1,
7348          1.0,   -1.0,     0.1,
7349          1.0,    0.0,     0.1,
7350
7351          0.0,    0.0,     0.1,
7352          0.0,    1.0,     0.1,
7353          1.0,    0.0,     0.1,
7354          1.0,    1.0,     0.1,
7355
7356         -1.0,    0.0,     0.1,
7357         -1.0,    1.0,     0.1,
7358          0.0,    0.0,     0.1,
7359          0.0,    1.0,     0.1
7360     };
7361     struct tvertex quad_transformed[] = {
7362        {  90,    110,     0.1,      2.0,        0x00ffff00},
7363        { 570,    110,     0.1,      2.0,        0x00ffff00},
7364        {  90,    300,     0.1,      2.0,        0x00ffff00},
7365        { 570,    300,     0.1,      2.0,        0x00ffff00}
7366     };
7367     D3DCAPS9 caps;
7368
7369     memset(&caps, 0, sizeof(caps));
7370     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7371     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7372
7373     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7374     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7375
7376     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7377     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7378     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7379     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7380     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7381     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7382     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7383         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7384         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7385         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7386         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7387     } else {
7388         trace("D3DDTCAPS_UBYTE4N not supported\n");
7389         dcl_ubyte_2 = NULL;
7390         dcl_ubyte = NULL;
7391     }
7392     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7393     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7394     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7395     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7396
7397     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7398     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7399                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7400     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7401
7402     hr = IDirect3DDevice9_BeginScene(device);
7403     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7404     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7405     if(SUCCEEDED(hr)) {
7406         if(dcl_color) {
7407             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7408             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7409             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7410             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7411         }
7412
7413         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7414          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7415          * using software vertex processing. Doh!
7416          */
7417         if(dcl_ubyte) {
7418             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7419             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7420             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7421             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7422             ub_ok = SUCCEEDED(hr);
7423         }
7424
7425         if(dcl_short) {
7426             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7427             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7428             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7429             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7430             s_ok = SUCCEEDED(hr);
7431         }
7432
7433         if(dcl_float) {
7434             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7435             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7436             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7437             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7438             f_ok = SUCCEEDED(hr);
7439         }
7440
7441         hr = IDirect3DDevice9_EndScene(device);
7442         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7443     }
7444
7445     if(dcl_short) {
7446         color = getPixelColor(device, 480, 360);
7447         ok(color == 0x000000ff || !s_ok,
7448            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7449     }
7450     if(dcl_ubyte) {
7451         color = getPixelColor(device, 160, 120);
7452         ok(color == 0x0000ffff || !ub_ok,
7453            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7454     }
7455     if(dcl_color) {
7456         color = getPixelColor(device, 160, 360);
7457         ok(color == 0x00ffff00,
7458            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7459     }
7460     if(dcl_float) {
7461         color = getPixelColor(device, 480, 120);
7462         ok(color == 0x00ff0000 || !f_ok,
7463            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7464     }
7465     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7466
7467     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7468      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7469      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7470      * whether the immediate mode code works
7471      */
7472     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7473     hr = IDirect3DDevice9_BeginScene(device);
7474     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7475     if(SUCCEEDED(hr)) {
7476         if(dcl_color) {
7477             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7478             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7479             memcpy(data, quad1, sizeof(quad1));
7480             hr = IDirect3DVertexBuffer9_Unlock(vb);
7481             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7482             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7483             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7484             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7485             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7486             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7487             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7488         }
7489
7490         if(dcl_ubyte) {
7491             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7492             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7493             memcpy(data, quad2, sizeof(quad2));
7494             hr = IDirect3DVertexBuffer9_Unlock(vb);
7495             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7496             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7497             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7498             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7499             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7500             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7501             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7502                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7503             ub_ok = SUCCEEDED(hr);
7504         }
7505
7506         if(dcl_short) {
7507             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7508             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7509             memcpy(data, quad3, sizeof(quad3));
7510             hr = IDirect3DVertexBuffer9_Unlock(vb);
7511             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7512             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7513             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7514             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7515             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7516             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7517             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7518                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7519             s_ok = SUCCEEDED(hr);
7520         }
7521
7522         if(dcl_float) {
7523             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7524             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7525             memcpy(data, quad4, sizeof(quad4));
7526             hr = IDirect3DVertexBuffer9_Unlock(vb);
7527             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7528             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7529             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7530             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7531             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7532             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7533             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7534                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7535             f_ok = SUCCEEDED(hr);
7536         }
7537
7538         hr = IDirect3DDevice9_EndScene(device);
7539         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7540     }
7541
7542     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7543     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7544     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7545     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7546
7547     if(dcl_short) {
7548         color = getPixelColor(device, 480, 360);
7549         ok(color == 0x000000ff || !s_ok,
7550            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7551     }
7552     if(dcl_ubyte) {
7553         color = getPixelColor(device, 160, 120);
7554         ok(color == 0x0000ffff || !ub_ok,
7555            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7556     }
7557     if(dcl_color) {
7558         color = getPixelColor(device, 160, 360);
7559         ok(color == 0x00ffff00,
7560            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7561     }
7562     if(dcl_float) {
7563         color = getPixelColor(device, 480, 120);
7564         ok(color == 0x00ff0000 || !f_ok,
7565            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7566     }
7567     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7568
7569     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7570     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7571
7572     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7573     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7574     memcpy(data, quad_transformed, sizeof(quad_transformed));
7575     hr = IDirect3DVertexBuffer9_Unlock(vb);
7576     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7577
7578     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7579     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7580
7581     hr = IDirect3DDevice9_BeginScene(device);
7582     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7583     if(SUCCEEDED(hr)) {
7584         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7585         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7586         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7587         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7588
7589         hr = IDirect3DDevice9_EndScene(device);
7590         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7591     }
7592
7593     color = getPixelColor(device, 88, 108);
7594     ok(color == 0x000000ff,
7595        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7596     color = getPixelColor(device, 92, 108);
7597     ok(color == 0x000000ff,
7598        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7599     color = getPixelColor(device, 88, 112);
7600     ok(color == 0x000000ff,
7601        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7602     color = getPixelColor(device, 92, 112);
7603     ok(color == 0x00ffff00,
7604        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7605
7606     color = getPixelColor(device, 568, 108);
7607     ok(color == 0x000000ff,
7608        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7609     color = getPixelColor(device, 572, 108);
7610     ok(color == 0x000000ff,
7611        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7612     color = getPixelColor(device, 568, 112);
7613     ok(color == 0x00ffff00,
7614        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7615     color = getPixelColor(device, 572, 112);
7616     ok(color == 0x000000ff,
7617        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7618
7619     color = getPixelColor(device, 88, 298);
7620     ok(color == 0x000000ff,
7621        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7622     color = getPixelColor(device, 92, 298);
7623     ok(color == 0x00ffff00,
7624        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7625     color = getPixelColor(device, 88, 302);
7626     ok(color == 0x000000ff,
7627        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7628     color = getPixelColor(device, 92, 302);
7629     ok(color == 0x000000ff,
7630        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7631
7632     color = getPixelColor(device, 568, 298);
7633     ok(color == 0x00ffff00,
7634        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7635     color = getPixelColor(device, 572, 298);
7636     ok(color == 0x000000ff,
7637        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7638     color = getPixelColor(device, 568, 302);
7639     ok(color == 0x000000ff,
7640        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7641     color = getPixelColor(device, 572, 302);
7642     ok(color == 0x000000ff,
7643        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7644
7645     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7646
7647     /* This test is pointless without those two declarations: */
7648     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7649         skip("color-ubyte switching test declarations aren't supported\n");
7650         goto out;
7651     }
7652
7653     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7654     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7655     memcpy(data, quads, sizeof(quads));
7656     hr = IDirect3DVertexBuffer9_Unlock(vb);
7657     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7658     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7659                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7660     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7661     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7662     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7663     memcpy(data, colors, sizeof(colors));
7664     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7665     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7666
7667     for(i = 0; i < 2; i++) {
7668         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7669         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7670
7671         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7672         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7673         if(i == 0) {
7674             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7675         } else {
7676             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7677         }
7678         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7679
7680         hr = IDirect3DDevice9_BeginScene(device);
7681         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7682         ub_ok = FALSE;
7683         if(SUCCEEDED(hr)) {
7684             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7685             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7686             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7687             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7688                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7689             ub_ok = SUCCEEDED(hr);
7690
7691             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7692             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7693             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7694             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7695
7696             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7697             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7698             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7699             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7700                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7701             ub_ok = (SUCCEEDED(hr) && ub_ok);
7702
7703             hr = IDirect3DDevice9_EndScene(device);
7704             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7705         }
7706
7707         if(i == 0) {
7708             color = getPixelColor(device, 480, 360);
7709             ok(color == 0x00ff0000,
7710                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7711             color = getPixelColor(device, 160, 120);
7712             ok(color == 0x00ffffff,
7713                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7714             color = getPixelColor(device, 160, 360);
7715             ok(color == 0x000000ff || !ub_ok,
7716                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7717             color = getPixelColor(device, 480, 120);
7718             ok(color == 0x000000ff || !ub_ok,
7719                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7720         } else {
7721             color = getPixelColor(device, 480, 360);
7722             ok(color == 0x000000ff,
7723                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7724             color = getPixelColor(device, 160, 120);
7725             ok(color == 0x00ffffff,
7726                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7727             color = getPixelColor(device, 160, 360);
7728             ok(color == 0x00ff0000 || !ub_ok,
7729                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7730             color = getPixelColor(device, 480, 120);
7731             ok(color == 0x00ff0000 || !ub_ok,
7732                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7733         }
7734         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7735     }
7736
7737     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7738     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7739     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7740     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7741     IDirect3DVertexBuffer9_Release(vb2);
7742
7743     out:
7744     IDirect3DVertexBuffer9_Release(vb);
7745     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7746     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7747     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7748     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7749     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7750     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7751     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7752 }
7753
7754 struct vertex_float16color {
7755     float x, y, z;
7756     DWORD c1, c2;
7757 };
7758
7759 static void test_vshader_float16(IDirect3DDevice9 *device)
7760 {
7761     HRESULT hr;
7762     DWORD color;
7763     void *data;
7764     static const D3DVERTEXELEMENT9 decl_elements[] = {
7765         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7766         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7767         D3DDECL_END()
7768     };
7769     IDirect3DVertexDeclaration9 *vdecl = NULL;
7770     IDirect3DVertexBuffer9 *buffer = NULL;
7771     IDirect3DVertexShader9 *shader;
7772     DWORD shader_code[] = {
7773         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7774         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7775         0x90e40001, 0x0000ffff
7776     };
7777     struct vertex_float16color quad[] = {
7778         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7779         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7780         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7781         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7782
7783         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7784         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7785         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7786         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7787
7788         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7789         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7790         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7791         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7792
7793         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7794         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7795         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7796         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7797     };
7798
7799     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7800     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7801
7802     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7803     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7804     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7805     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7806     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7807     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7808
7809     hr = IDirect3DDevice9_BeginScene(device);
7810     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7811     if(SUCCEEDED(hr)) {
7812         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7813         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7814         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7815         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7816         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7817         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7818         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7819         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7820         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7821         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7822
7823         hr = IDirect3DDevice9_EndScene(device);
7824         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7825     }
7826     color = getPixelColor(device, 480, 360);
7827     ok(color == 0x00ff0000,
7828        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7829     color = getPixelColor(device, 160, 120);
7830     ok(color == 0x00000000,
7831        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7832     color = getPixelColor(device, 160, 360);
7833     ok(color == 0x0000ff00,
7834        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7835     color = getPixelColor(device, 480, 120);
7836     ok(color == 0x000000ff,
7837        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7838     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7839
7840     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7841     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7842
7843     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7844                                              D3DPOOL_MANAGED, &buffer, NULL);
7845     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7846     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7847     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7848     memcpy(data, quad, sizeof(quad));
7849     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7850     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7851     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7852     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7853
7854     hr = IDirect3DDevice9_BeginScene(device);
7855     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7856     if(SUCCEEDED(hr)) {
7857             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7858             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7859             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7860             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7861             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7862             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7863             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7864             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7865
7866             hr = IDirect3DDevice9_EndScene(device);
7867             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7868     }
7869
7870     color = getPixelColor(device, 480, 360);
7871     ok(color == 0x00ff0000,
7872        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7873     color = getPixelColor(device, 160, 120);
7874     ok(color == 0x00000000,
7875        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7876     color = getPixelColor(device, 160, 360);
7877     ok(color == 0x0000ff00,
7878        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7879     color = getPixelColor(device, 480, 120);
7880     ok(color == 0x000000ff,
7881        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7882     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7883
7884     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7885     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7886     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7887     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7888     IDirect3DDevice9_SetVertexShader(device, NULL);
7889     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7890
7891     IDirect3DVertexDeclaration9_Release(vdecl);
7892     IDirect3DVertexShader9_Release(shader);
7893     IDirect3DVertexBuffer9_Release(buffer);
7894 }
7895
7896 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7897 {
7898     D3DCAPS9 caps;
7899     IDirect3DTexture9 *texture;
7900     HRESULT hr;
7901     D3DLOCKED_RECT rect;
7902     unsigned int x, y;
7903     DWORD *dst, color;
7904     const float quad[] = {
7905         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7906          1.0,   -1.0,   0.1,    1.2,   -0.2,
7907         -1.0,    1.0,   0.1,   -0.2,    1.2,
7908          1.0,    1.0,   0.1,    1.2,    1.2
7909     };
7910     memset(&caps, 0, sizeof(caps));
7911
7912     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7913     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7914     if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
7915     {
7916         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7917         ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
7918                 "Card has conditional NP2 support without power of two restriction set\n");
7919     }
7920     else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
7921     {
7922         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7923         return;
7924     }
7925     else
7926     {
7927         skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
7928         return;
7929     }
7930
7931     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7932     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7933
7934     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7935     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7936
7937     memset(&rect, 0, sizeof(rect));
7938     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7939     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7940     for(y = 0; y < 10; y++) {
7941         for(x = 0; x < 10; x++) {
7942             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7943             if(x == 0 || x == 9 || y == 0 || y == 9) {
7944                 *dst = 0x00ff0000;
7945             } else {
7946                 *dst = 0x000000ff;
7947             }
7948         }
7949     }
7950     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7951     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7952
7953     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7954     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7955     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7956     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7957     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7958     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7959     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7960     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7961
7962     hr = IDirect3DDevice9_BeginScene(device);
7963     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7964     if(SUCCEEDED(hr)) {
7965         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7966         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7967
7968         hr = IDirect3DDevice9_EndScene(device);
7969         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7970     }
7971
7972     color = getPixelColor(device,    1,  1);
7973     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7974     color = getPixelColor(device, 639, 479);
7975     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7976
7977     color = getPixelColor(device, 135, 101);
7978     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7979     color = getPixelColor(device, 140, 101);
7980     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7981     color = getPixelColor(device, 135, 105);
7982     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7983     color = getPixelColor(device, 140, 105);
7984     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7985
7986     color = getPixelColor(device, 135, 376);
7987     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7988     color = getPixelColor(device, 140, 376);
7989     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7990     color = getPixelColor(device, 135, 379);
7991     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7992     color = getPixelColor(device, 140, 379);
7993     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7994
7995     color = getPixelColor(device, 500, 101);
7996     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7997     color = getPixelColor(device, 504, 101);
7998     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7999     color = getPixelColor(device, 500, 105);
8000     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
8001     color = getPixelColor(device, 504, 105);
8002     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
8003
8004     color = getPixelColor(device, 500, 376);
8005     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
8006     color = getPixelColor(device, 504, 376);
8007     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
8008     color = getPixelColor(device, 500, 380);
8009     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
8010     color = getPixelColor(device, 504, 380);
8011     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
8012
8013     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8014
8015     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8016     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8017     IDirect3DTexture9_Release(texture);
8018 }
8019
8020 static void vFace_register_test(IDirect3DDevice9 *device)
8021 {
8022     HRESULT hr;
8023     DWORD color;
8024     const DWORD shader_code[] = {
8025         0xffff0300,                                                             /* ps_3_0                     */
8026         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8027         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
8028         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
8029         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
8030         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
8031         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8032         0x0000ffff                                                              /* END                        */
8033     };
8034     const DWORD vshader_code[] = {
8035         0xfffe0300,                                                             /* vs_3_0               */
8036         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8037         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8038         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8039         0x0000ffff                                                              /* end                  */
8040     };
8041     IDirect3DPixelShader9 *shader;
8042     IDirect3DVertexShader9 *vshader;
8043     IDirect3DTexture9 *texture;
8044     IDirect3DSurface9 *surface, *backbuffer;
8045     const float quad[] = {
8046         -1.0,   -1.0,   0.1,
8047          1.0,   -1.0,   0.1,
8048         -1.0,    0.0,   0.1,
8049
8050          1.0,   -1.0,   0.1,
8051          1.0,    0.0,   0.1,
8052         -1.0,    0.0,   0.1,
8053
8054         -1.0,    0.0,   0.1,
8055         -1.0,    1.0,   0.1,
8056          1.0,    0.0,   0.1,
8057
8058          1.0,    0.0,   0.1,
8059         -1.0,    1.0,   0.1,
8060          1.0,    1.0,   0.1,
8061     };
8062     const float blit[] = {
8063          0.0,   -1.0,   0.1,    0.0,    0.0,
8064          1.0,   -1.0,   0.1,    1.0,    0.0,
8065          0.0,    1.0,   0.1,    0.0,    1.0,
8066          1.0,    1.0,   0.1,    1.0,    1.0,
8067     };
8068
8069     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8070     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8071     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8072     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8073     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8074     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8075     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8076     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8077     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8078     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8079     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8080     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8081     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8082     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8083     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8084     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8085
8086     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8087     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8088
8089     hr = IDirect3DDevice9_BeginScene(device);
8090     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8091     if(SUCCEEDED(hr)) {
8092         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8093         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8094         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8095         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8096         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8097         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8098         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8099         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8100         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8101         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8102         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8103
8104         /* Blit the texture onto the back buffer to make it visible */
8105         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8106         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
8107         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8108         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8109         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8110         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8111         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8112         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8113         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8114         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8115         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8116         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8117
8118         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8119         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8120
8121         hr = IDirect3DDevice9_EndScene(device);
8122         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8123     }
8124
8125     color = getPixelColor(device, 160, 360);
8126     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8127     color = getPixelColor(device, 160, 120);
8128     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8129     color = getPixelColor(device, 480, 360);
8130     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8131     color = getPixelColor(device, 480, 120);
8132     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8133     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8134
8135     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8136     IDirect3DDevice9_SetTexture(device, 0, NULL);
8137     IDirect3DPixelShader9_Release(shader);
8138     IDirect3DVertexShader9_Release(vshader);
8139     IDirect3DSurface9_Release(surface);
8140     IDirect3DSurface9_Release(backbuffer);
8141     IDirect3DTexture9_Release(texture);
8142 }
8143
8144 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8145 {
8146     HRESULT hr;
8147     DWORD color;
8148     int i;
8149     D3DCAPS9 caps;
8150     BOOL L6V5U5_supported = FALSE;
8151     IDirect3DTexture9 *tex1, *tex2;
8152     D3DLOCKED_RECT locked_rect;
8153
8154     static const float quad[][7] = {
8155         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8156         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8157         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8158         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8159     };
8160
8161     static const D3DVERTEXELEMENT9 decl_elements[] = {
8162         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8163         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8164         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8165         D3DDECL_END()
8166     };
8167
8168     /* use asymmetric matrix to test loading */
8169     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8170     float scale, offset;
8171
8172     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8173     IDirect3DTexture9           *texture            = NULL;
8174
8175     memset(&caps, 0, sizeof(caps));
8176     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8177     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8178     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8179         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8180         return;
8181     } else {
8182         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8183          * They report that it is not supported, but after that bump mapping works properly. So just test
8184          * if the format is generally supported, and check the BUMPENVMAP flag
8185          */
8186         IDirect3D9 *d3d9;
8187
8188         IDirect3DDevice9_GetDirect3D(device, &d3d9);
8189         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8190                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8191         L6V5U5_supported = SUCCEEDED(hr);
8192         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8193                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8194         IDirect3D9_Release(d3d9);
8195         if(FAILED(hr)) {
8196             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8197             return;
8198         }
8199     }
8200
8201     /* Generate the textures */
8202     generate_bumpmap_textures(device);
8203
8204     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8205     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8206     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8207     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8208     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8209     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8210     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8211     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8212
8213     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8214     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8215     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8216     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8217     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8218     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8219
8220     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8221     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8222     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8223     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8224     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8225     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8226
8227     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8228     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8229
8230     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8231     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8232
8233     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8234     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8235
8236
8237     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8238     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8239     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8240     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8241
8242     hr = IDirect3DDevice9_BeginScene(device);
8243     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8244
8245     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8246     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8247
8248     hr = IDirect3DDevice9_EndScene(device);
8249     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8250
8251     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8252      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8253      * But since testing the color match is not the purpose of the test don't be too picky
8254      */
8255     color = getPixelColor(device, 320-32, 240);
8256     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8257     color = getPixelColor(device, 320+32, 240);
8258     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8259     color = getPixelColor(device, 320, 240-32);
8260     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8261     color = getPixelColor(device, 320, 240+32);
8262     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8263     color = getPixelColor(device, 320, 240);
8264     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8265     color = getPixelColor(device, 320+32, 240+32);
8266     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8267     color = getPixelColor(device, 320-32, 240+32);
8268     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8269     color = getPixelColor(device, 320+32, 240-32);
8270     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8271     color = getPixelColor(device, 320-32, 240-32);
8272     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8273     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8274     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8275
8276     for(i = 0; i < 2; i++) {
8277         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8278         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8279         IDirect3DTexture9_Release(texture); /* For the GetTexture */
8280         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8281         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8282         IDirect3DTexture9_Release(texture); /* To destroy it */
8283     }
8284
8285     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8286         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8287         goto cleanup;
8288     }
8289     if(L6V5U5_supported == FALSE) {
8290         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8291         goto cleanup;
8292     }
8293
8294     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8295     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8296     /* This test only tests the luminance part. The bumpmapping part was already tested above and
8297      * would only make this test more complicated
8298      */
8299     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8300     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8301     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8302     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8303
8304     memset(&locked_rect, 0, sizeof(locked_rect));
8305     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8306     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8307     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8308     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8309     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8310
8311     memset(&locked_rect, 0, sizeof(locked_rect));
8312     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8313     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8314     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8315     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8316     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8317
8318     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8319     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8320     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8321     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8322
8323     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8324     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8325     scale = 2.0;
8326     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8327     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8328     offset = 0.1;
8329     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8330     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8331
8332     hr = IDirect3DDevice9_BeginScene(device);
8333     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8334     if(SUCCEEDED(hr)) {
8335         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8336         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8337         hr = IDirect3DDevice9_EndScene(device);
8338         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8339     }
8340
8341     color = getPixelColor(device, 320, 240);
8342     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
8343      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
8344      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8345      */
8346     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8347     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8348     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8349
8350     /* Check a result scale factor > 1.0 */
8351     scale = 10;
8352     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8353     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8354     offset = 10;
8355     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8356     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8357
8358     hr = IDirect3DDevice9_BeginScene(device);
8359     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8360     if(SUCCEEDED(hr)) {
8361         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8362         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8363         hr = IDirect3DDevice9_EndScene(device);
8364         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8365     }
8366     color = getPixelColor(device, 320, 240);
8367     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8368     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8369     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8370
8371     /* Check clamping in the scale factor calculation */
8372     scale = 1000;
8373     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8374     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8375     offset = -1;
8376     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8377     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8378
8379     hr = IDirect3DDevice9_BeginScene(device);
8380     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8381     if(SUCCEEDED(hr)) {
8382         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8383         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8384         hr = IDirect3DDevice9_EndScene(device);
8385         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8386     }
8387     color = getPixelColor(device, 320, 240);
8388     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8389     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8390     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8391
8392     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8393     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8394     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8395     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8396
8397     IDirect3DTexture9_Release(tex1);
8398     IDirect3DTexture9_Release(tex2);
8399
8400 cleanup:
8401     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8402     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8403     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8404     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8405
8406     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8407     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8408     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8409 }
8410
8411 static void stencil_cull_test(IDirect3DDevice9 *device) {
8412     HRESULT hr;
8413     IDirect3DSurface9 *depthstencil = NULL;
8414     D3DSURFACE_DESC desc;
8415     float quad1[] = {
8416         -1.0,   -1.0,   0.1,
8417          0.0,   -1.0,   0.1,
8418         -1.0,    0.0,   0.1,
8419          0.0,    0.0,   0.1,
8420     };
8421     float quad2[] = {
8422          0.0,   -1.0,   0.1,
8423          1.0,   -1.0,   0.1,
8424          0.0,    0.0,   0.1,
8425          1.0,    0.0,   0.1,
8426     };
8427     float quad3[] = {
8428         0.0,    0.0,   0.1,
8429         1.0,    0.0,   0.1,
8430         0.0,    1.0,   0.1,
8431         1.0,    1.0,   0.1,
8432     };
8433     float quad4[] = {
8434         -1.0,    0.0,   0.1,
8435          0.0,    0.0,   0.1,
8436         -1.0,    1.0,   0.1,
8437          0.0,    1.0,   0.1,
8438     };
8439     struct vertex painter[] = {
8440        {-1.0,   -1.0,   0.0,    0x00000000},
8441        { 1.0,   -1.0,   0.0,    0x00000000},
8442        {-1.0,    1.0,   0.0,    0x00000000},
8443        { 1.0,    1.0,   0.0,    0x00000000},
8444     };
8445     WORD indices_cw[]  = {0, 1, 3};
8446     WORD indices_ccw[] = {0, 2, 3};
8447     unsigned int i;
8448     DWORD color;
8449
8450     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8451     if(depthstencil == NULL) {
8452         skip("No depth stencil buffer\n");
8453         return;
8454     }
8455     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8456     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8457     IDirect3DSurface9_Release(depthstencil);
8458     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8459         skip("No 4 or 8 bit stencil surface\n");
8460         return;
8461     }
8462
8463     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8464     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8465     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8466
8467     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8468     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8469     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8470     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8471     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8472     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8473     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8474     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8475
8476     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8477     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8478     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8479     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8480     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8481     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8482
8483     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8484     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8485     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8486     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8487
8488     /* First pass: Fill the stencil buffer with some values... */
8489     hr = IDirect3DDevice9_BeginScene(device);
8490     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8491     if(SUCCEEDED(hr))
8492     {
8493         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8494         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8495         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8496                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8497         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8498         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8499                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8500         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8501
8502         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8503         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8504         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8505         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8506         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8507                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8508         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8509         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8510                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8511         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8512
8513         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8514         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8515         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8516                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8517         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8518         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8519                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8520         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8521
8522         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8523         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8524         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8525                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8526         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8527         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8528                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8529         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8530
8531         hr = IDirect3DDevice9_EndScene(device);
8532         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8533     }
8534
8535     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8536     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8537     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8538     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8539     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8540     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8541     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8542     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8543     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8544     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8545     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8546     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8547     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8548
8549     /* 2nd pass: Make the stencil values visible */
8550     hr = IDirect3DDevice9_BeginScene(device);
8551     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8552     if(SUCCEEDED(hr))
8553     {
8554         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8555         for(i = 0; i < 16; i++) {
8556             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8557             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8558
8559             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8560             painter[1].diffuse = (i * 16);
8561             painter[2].diffuse = (i * 16);
8562             painter[3].diffuse = (i * 16);
8563             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8564             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8565         }
8566         hr = IDirect3DDevice9_EndScene(device);
8567         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8568     }
8569
8570     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8571     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8572
8573     color = getPixelColor(device, 160, 420);
8574     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8575     color = getPixelColor(device, 160, 300);
8576     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8577
8578     color = getPixelColor(device, 480, 420);
8579     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8580     color = getPixelColor(device, 480, 300);
8581     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8582
8583     color = getPixelColor(device, 160, 180);
8584     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8585     color = getPixelColor(device, 160, 60);
8586     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8587
8588     color = getPixelColor(device, 480, 180);
8589     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8590     color = getPixelColor(device, 480, 60);
8591     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8592
8593     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8594     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8595 }
8596
8597 static void vpos_register_test(IDirect3DDevice9 *device)
8598 {
8599     HRESULT hr;
8600     DWORD color;
8601     const DWORD shader_code[] = {
8602     0xffff0300,                                                             /* ps_3_0                     */
8603     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8604     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8605     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8606     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8607     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8608     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8609     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8610     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8611     0x0000ffff                                                              /* end                        */
8612     };
8613     const DWORD shader_frac_code[] = {
8614     0xffff0300,                                                             /* ps_3_0                     */
8615     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8616     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8617     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8618     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8619     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8620     0x0000ffff                                                              /* end                        */
8621     };
8622     const DWORD vshader_code[] = {
8623         0xfffe0300,                                                             /* vs_3_0               */
8624         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8625         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8626         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8627         0x0000ffff                                                              /* end                  */
8628     };
8629     IDirect3DVertexShader9 *vshader;
8630     IDirect3DPixelShader9 *shader, *shader_frac;
8631     IDirect3DSurface9 *surface = NULL, *backbuffer;
8632     const float quad[] = {
8633         -1.0,   -1.0,   0.1,    0.0,    0.0,
8634          1.0,   -1.0,   0.1,    1.0,    0.0,
8635         -1.0,    1.0,   0.1,    0.0,    1.0,
8636          1.0,    1.0,   0.1,    1.0,    1.0,
8637     };
8638     D3DLOCKED_RECT lr;
8639     float constant[4] = {1.0, 0.0, 320, 240};
8640     DWORD *pos;
8641
8642     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8643     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8644     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8645     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8646     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8647     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8648     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8649     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8650     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8651     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8652     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8653     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8654     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8655     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8656     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8657     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8658
8659     hr = IDirect3DDevice9_BeginScene(device);
8660     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8661     if(SUCCEEDED(hr)) {
8662         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8663         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8664         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8665         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8666         hr = IDirect3DDevice9_EndScene(device);
8667         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8668     }
8669
8670     /* This has to be pixel exact */
8671     color = getPixelColor(device, 319, 239);
8672     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8673     color = getPixelColor(device, 320, 239);
8674     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8675     color = getPixelColor(device, 319, 240);
8676     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8677     color = getPixelColor(device, 320, 240);
8678     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8679     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8680
8681     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8682                                              &surface, NULL);
8683     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8684     hr = IDirect3DDevice9_BeginScene(device);
8685     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8686     if(SUCCEEDED(hr)) {
8687         constant[2] = 16; constant[3] = 16;
8688         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8689         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8690         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8691         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8692         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8693         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8694         hr = IDirect3DDevice9_EndScene(device);
8695         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8696     }
8697     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8698     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8699
8700     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8701     color = *pos & 0x00ffffff;
8702     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8703     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8704     color = *pos & 0x00ffffff;
8705     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8706     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8707     color = *pos & 0x00ffffff;
8708     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8709     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8710     color = *pos & 0x00ffffff;
8711     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8712
8713     hr = IDirect3DSurface9_UnlockRect(surface);
8714     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8715
8716     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8717      * have full control over the multisampling setting inside this test
8718      */
8719     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8720     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8721     hr = IDirect3DDevice9_BeginScene(device);
8722     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8723     if(SUCCEEDED(hr)) {
8724         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8725         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8726         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8727         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8728         hr = IDirect3DDevice9_EndScene(device);
8729         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8730     }
8731     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8732     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8733
8734     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8735     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8736
8737     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8738     color = *pos & 0x00ffffff;
8739     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8740
8741     hr = IDirect3DSurface9_UnlockRect(surface);
8742     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8743
8744     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8745     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8746     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8747     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8748     IDirect3DPixelShader9_Release(shader);
8749     IDirect3DPixelShader9_Release(shader_frac);
8750     IDirect3DVertexShader9_Release(vshader);
8751     if(surface) IDirect3DSurface9_Release(surface);
8752     IDirect3DSurface9_Release(backbuffer);
8753 }
8754
8755 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8756 {
8757     D3DCOLOR color;
8758
8759     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8760     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8761     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8762     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8763     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8764
8765     ++r;
8766     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8767     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8768     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8769     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8770     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8771
8772     return TRUE;
8773 }
8774
8775 static void pointsize_test(IDirect3DDevice9 *device)
8776 {
8777     HRESULT hr;
8778     D3DCAPS9 caps;
8779     D3DMATRIX matrix;
8780     D3DMATRIX identity;
8781     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8782     DWORD color;
8783     IDirect3DSurface9 *rt, *backbuffer;
8784     IDirect3DTexture9 *tex1, *tex2;
8785     RECT rect = {0, 0, 128, 128};
8786     D3DLOCKED_RECT lr;
8787     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8788                                 0x00000000, 0x00000000};
8789     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8790                                 0x00000000, 0x0000ff00};
8791
8792     const float vertices[] = {
8793         64,     64,     0.1,
8794         128,    64,     0.1,
8795         192,    64,     0.1,
8796         256,    64,     0.1,
8797         320,    64,     0.1,
8798         384,    64,     0.1,
8799         448,    64,     0.1,
8800         512,    64,     0.1,
8801     };
8802
8803     /* 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 */
8804     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;
8805     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;
8806     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;
8807     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;
8808
8809     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;
8810     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;
8811     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;
8812     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;
8813
8814     memset(&caps, 0, sizeof(caps));
8815     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8816     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8817     if(caps.MaxPointSize < 32.0) {
8818         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8819         return;
8820     }
8821
8822     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8823     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8824     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8825     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8826     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8827     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8828     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8829     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8830
8831     hr = IDirect3DDevice9_BeginScene(device);
8832     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8833     if (SUCCEEDED(hr))
8834     {
8835         ptsize = 15.0;
8836         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8837         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8838         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8839         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8840
8841         ptsize = 31.0;
8842         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8843         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8844         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8845         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8846
8847         ptsize = 30.75;
8848         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8849         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8850         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8851         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8852
8853         if (caps.MaxPointSize >= 63.0)
8854         {
8855             ptsize = 63.0;
8856             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8857             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8858             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8859             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8860
8861             ptsize = 62.75;
8862             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8863             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8864             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8865             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8866         }
8867
8868         ptsize = 1.0;
8869         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8870         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8871         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8872         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8873
8874         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8875         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8876         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8877         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8878
8879         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8880         ptsize = 15.0;
8881         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8882         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8883         ptsize = 1.0;
8884         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8885         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8886         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8887         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8888
8889         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8890         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8891
8892         /* pointsize < pointsize_min < pointsize_max?
8893          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8894         ptsize = 1.0;
8895         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8896         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8897         ptsize = 15.0;
8898         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8899         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8900         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8901         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8902
8903         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8904         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8905
8906         hr = IDirect3DDevice9_EndScene(device);
8907         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8908     }
8909
8910     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8911     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8912     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8913
8914     if (caps.MaxPointSize >= 63.0)
8915     {
8916         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8917         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8918     }
8919
8920     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8921     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8922     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8923     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8924     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8925
8926     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8927
8928     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8929      * generates texture coordinates for the point(result: Yes, it does)
8930      *
8931      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8932      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8933      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8934      */
8935     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8936     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8937
8938     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8939     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8940     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8941     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8942     memset(&lr, 0, sizeof(lr));
8943     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8944     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8945     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8946     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8947     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8948     memset(&lr, 0, sizeof(lr));
8949     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8950     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8951     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8952     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8953     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8954     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8955     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8956     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8957     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8958     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8959     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8960     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8961     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8962     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8963     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8964     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8965     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8966     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8967     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8968
8969     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8970     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8971     ptsize = 32.0;
8972     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8973     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8974
8975     hr = IDirect3DDevice9_BeginScene(device);
8976     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8977     if(SUCCEEDED(hr))
8978     {
8979         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8980         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8981         hr = IDirect3DDevice9_EndScene(device);
8982         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8983     }
8984
8985     color = getPixelColor(device, 64-4, 64-4);
8986     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8987     color = getPixelColor(device, 64-4, 64+4);
8988     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8989     color = getPixelColor(device, 64+4, 64+4);
8990     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8991     color = getPixelColor(device, 64+4, 64-4);
8992     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8993     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8994
8995     U(matrix).m[0][0] =  1.0f / 64.0f;
8996     U(matrix).m[1][1] = -1.0f / 64.0f;
8997     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8998     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8999
9000     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
9001     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
9002
9003     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
9004             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
9005     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
9006
9007     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
9008     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9009     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
9010     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
9011
9012     hr = IDirect3DDevice9_BeginScene(device);
9013     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9014     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9015     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9016     hr = IDirect3DDevice9_EndScene(device);
9017     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9018
9019     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
9020     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
9021     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9022     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9023     IDirect3DSurface9_Release(backbuffer);
9024     IDirect3DSurface9_Release(rt);
9025
9026     color = getPixelColor(device, 64-4, 64-4);
9027     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
9028             "Expected color 0x00ff0000, got 0x%08x.\n", color);
9029     color = getPixelColor(device, 64+4, 64-4);
9030     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
9031             "Expected color 0x00ffff00, got 0x%08x.\n", color);
9032     color = getPixelColor(device, 64-4, 64+4);
9033     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
9034             "Expected color 0x00000000, got 0x%08x.\n", color);
9035     color = getPixelColor(device, 64+4, 64+4);
9036     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9037             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9038
9039     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9040     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9041
9042     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9043     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9044     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9045     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9046     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9047     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9048     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9049     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9050     IDirect3DTexture9_Release(tex1);
9051     IDirect3DTexture9_Release(tex2);
9052
9053     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9054     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9055     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9056     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9057     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9058     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9059 }
9060
9061 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9062 {
9063     static const DWORD vshader_code[] =
9064     {
9065         0xfffe0300,                                                             /* vs_3_0                     */
9066         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0            */
9067         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0            */
9068         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                 */
9069         0x0000ffff                                                              /* end                        */
9070     };
9071     static const DWORD pshader_code1[] =
9072     {
9073         0xffff0300,                                                             /* ps_3_0                     */
9074         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9075         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
9076         0x0000ffff                                                              /* end                        */
9077     };
9078     static const DWORD pshader_code2[] =
9079     {
9080         0xffff0300,                                                             /* ps_3_0                     */
9081         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9082         0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
9083         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
9084         0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1                */
9085         0x0000ffff                                                              /* end                        */
9086     };
9087
9088     HRESULT hr;
9089     IDirect3DVertexShader9 *vs;
9090     IDirect3DPixelShader9 *ps1, *ps2;
9091     IDirect3DTexture9 *tex1, *tex2;
9092     IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
9093     D3DCAPS9 caps;
9094     DWORD color;
9095     UINT i, j;
9096     float quad[] = {
9097        -1.0,   -1.0,    0.1,
9098         1.0,   -1.0,    0.1,
9099        -1.0,    1.0,    0.1,
9100         1.0,    1.0,    0.1,
9101     };
9102     float texquad[] = {
9103        -1.0,   -1.0,    0.1,    0.0,    0.0,
9104         0.0,   -1.0,    0.1,    1.0,    0.0,
9105        -1.0,    1.0,    0.1,    0.0,    1.0,
9106         0.0,    1.0,    0.1,    1.0,    1.0,
9107
9108         0.0,   -1.0,    0.1,    0.0,    0.0,
9109         1.0,   -1.0,    0.1,    1.0,    0.0,
9110         0.0,    1.0,    0.1,    0.0,    1.0,
9111         1.0,    1.0,    0.1,    1.0,    1.0,
9112     };
9113
9114     memset(&caps, 0, sizeof(caps));
9115     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9116     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9117     if(caps.NumSimultaneousRTs < 2) {
9118         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9119         return;
9120     }
9121
9122     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9123     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9124
9125     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
9126             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
9127     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
9128
9129     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9130             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9131     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9132     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9133             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9134     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9135     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
9136     ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
9137     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
9138     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9139     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
9140     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9141
9142     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9143     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9144     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9145     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9146     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9147     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9148
9149     hr = IDirect3DDevice9_SetVertexShader(device, vs);
9150     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9151     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9152     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9153     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9154     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9155     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9156     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9157
9158     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
9159     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9160     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9161     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9162     color = getPixelColorFromSurface(readback, 8, 8);
9163     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9164             "Expected color 0x000000ff, got 0x%08x.\n", color);
9165     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9166     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9167     color = getPixelColorFromSurface(readback, 8, 8);
9168     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9169             "Expected color 0x000000ff, got 0x%08x.\n", color);
9170
9171     /* Render targets not written by the pixel shader should be unmodified. */
9172     hr = IDirect3DDevice9_SetPixelShader(device, ps1);
9173     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9174     hr = IDirect3DDevice9_BeginScene(device);
9175     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9176     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9177     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9178     hr = IDirect3DDevice9_EndScene(device);
9179     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9180     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9181     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9182     color = getPixelColorFromSurface(readback, 8, 8);
9183     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9184             "Expected color 0xff00ff00, got 0x%08x.\n", color);
9185     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9186     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9187     for (i = 6; i < 10; ++i)
9188     {
9189         for (j = 6; j < 10; ++j)
9190         {
9191             color = getPixelColorFromSurface(readback, j, i);
9192             ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9193                     "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
9194         }
9195     }
9196
9197     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9198     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9199     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9200     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9201     color = getPixelColorFromSurface(readback, 8, 8);
9202     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9203             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9204     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9205     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9206     color = getPixelColorFromSurface(readback, 8, 8);
9207     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9208             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9209
9210     hr = IDirect3DDevice9_SetPixelShader(device, ps2);
9211     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9212
9213     hr = IDirect3DDevice9_BeginScene(device);
9214     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9215     if(SUCCEEDED(hr)) {
9216         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9217         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9218
9219         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9220         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9221         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9222         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9223         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9224         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9225         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9226         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9227         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9228         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9229
9230         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9231         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9232         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9233         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9234
9235         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9236         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9237         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9238         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9239
9240         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9241         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9242
9243         hr = IDirect3DDevice9_EndScene(device);
9244         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9245     }
9246
9247     color = getPixelColor(device, 160, 240);
9248     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9249     color = getPixelColor(device, 480, 240);
9250     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9251     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9252
9253     IDirect3DPixelShader9_Release(ps2);
9254     IDirect3DPixelShader9_Release(ps1);
9255     IDirect3DVertexShader9_Release(vs);
9256     IDirect3DTexture9_Release(tex1);
9257     IDirect3DTexture9_Release(tex2);
9258     IDirect3DSurface9_Release(surf1);
9259     IDirect3DSurface9_Release(surf2);
9260     IDirect3DSurface9_Release(backbuf);
9261     IDirect3DSurface9_Release(readback);
9262 }
9263
9264 struct formats {
9265     const char *fmtName;
9266     D3DFORMAT textureFormat;
9267     DWORD resultColorBlending;
9268     DWORD resultColorNoBlending;
9269 };
9270
9271 static const struct formats test_formats[] = {
9272   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9273   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9274   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9275   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9276   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9277   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9278   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9279   { NULL, 0 }
9280 };
9281
9282 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9283 {
9284     HRESULT hr;
9285     IDirect3DTexture9 *offscreenTexture = NULL;
9286     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9287     IDirect3D9 *d3d = NULL;
9288     DWORD color;
9289     DWORD r0, g0, b0, r1, g1, b1;
9290     int fmt_index;
9291
9292     static const float quad[][5] = {
9293         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9294         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
9295         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9296         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
9297     };
9298
9299     /* Quad with R=0x10, G=0x20 */
9300     static const struct vertex quad1[] = {
9301         {-1.0f, -1.0f, 0.1f, 0x80102000},
9302         {-1.0f,  1.0f, 0.1f, 0x80102000},
9303         { 1.0f, -1.0f, 0.1f, 0x80102000},
9304         { 1.0f,  1.0f, 0.1f, 0x80102000},
9305     };
9306
9307     /* Quad with R=0x20, G=0x10 */
9308     static const struct vertex quad2[] = {
9309         {-1.0f, -1.0f, 0.1f, 0x80201000},
9310         {-1.0f,  1.0f, 0.1f, 0x80201000},
9311         { 1.0f, -1.0f, 0.1f, 0x80201000},
9312         { 1.0f,  1.0f, 0.1f, 0x80201000},
9313     };
9314
9315     IDirect3DDevice9_GetDirect3D(device, &d3d);
9316
9317     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9318     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9319     if(!backbuffer) {
9320         goto out;
9321     }
9322
9323     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9324     {
9325         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9326
9327         if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9328                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
9329         {
9330             skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
9331             continue;
9332         }
9333
9334         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9335         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9336
9337         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9338         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9339         if(!offscreenTexture) {
9340             continue;
9341         }
9342
9343         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9344         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9345         if(!offscreen) {
9346             continue;
9347         }
9348
9349         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9350         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9351
9352         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9353         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9354         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9355         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9356         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9357         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9358         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9359         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9360         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9361         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9362
9363         /* Below we will draw two quads with different colors and try to blend them together.
9364          * The result color is compared with the expected outcome.
9365          */
9366         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9367             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9368             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9369             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9370             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9371
9372             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9373             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9374
9375             /* Draw a quad using color 0x0010200 */
9376             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9377             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9378             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9379             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9380             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9381             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9382
9383             /* Draw a quad using color 0x0020100 */
9384             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9385             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9386             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9387             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9388             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9389             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9390
9391             /* We don't want to blend the result on the backbuffer */
9392             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9393             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9394
9395             /* Prepare rendering the 'blended' texture quad to the backbuffer */
9396             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9397             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9398             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9399             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9400
9401             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9402             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9403
9404             /* This time with the texture */
9405             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9406             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9407
9408             IDirect3DDevice9_EndScene(device);
9409         }
9410
9411         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9412             /* Compare the color of the center quad with our expectation */
9413             color = getPixelColor(device, 320, 240);
9414             r0 = (color & 0x00ff0000) >> 16;
9415             g0 = (color & 0x0000ff00) >>  8;
9416             b0 = (color & 0x000000ff) >>  0;
9417
9418             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9419             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9420             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9421
9422             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9423                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9424                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9425                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9426         } else {
9427             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9428              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9429              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9430             color = getPixelColor(device, 320, 240);
9431             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);
9432         }
9433         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9434
9435         IDirect3DDevice9_SetTexture(device, 0, NULL);
9436         if(offscreenTexture) {
9437             IDirect3DTexture9_Release(offscreenTexture);
9438         }
9439         if(offscreen) {
9440             IDirect3DSurface9_Release(offscreen);
9441         }
9442     }
9443
9444 out:
9445     /* restore things */
9446     if(backbuffer) {
9447         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9448         IDirect3DSurface9_Release(backbuffer);
9449     }
9450 }
9451
9452 static void tssargtemp_test(IDirect3DDevice9 *device)
9453 {
9454     HRESULT hr;
9455     DWORD color;
9456     static const struct vertex quad[] = {
9457         {-1.0,     -1.0,    0.1,    0x00ff0000},
9458         { 1.0,     -1.0,    0.1,    0x00ff0000},
9459         {-1.0,      1.0,    0.1,    0x00ff0000},
9460         { 1.0,      1.0,    0.1,    0x00ff0000}
9461     };
9462     D3DCAPS9 caps;
9463
9464     memset(&caps, 0, sizeof(caps));
9465     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9466     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9467     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9468         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9469         return;
9470     }
9471
9472     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9473     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9474
9475     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9476     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9477     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9478     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9479
9480     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9481     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9482     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9483     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9484     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9485     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9486
9487     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9488     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9489     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9490     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9491     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9492     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9493
9494     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9495     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9496
9497     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9498     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9499     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9500     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9501
9502     hr = IDirect3DDevice9_BeginScene(device);
9503     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9504     if(SUCCEEDED(hr)) {
9505         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9506         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9507         hr = IDirect3DDevice9_EndScene(device);
9508         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9509     }
9510     color = getPixelColor(device, 320, 240);
9511     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9512     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9513
9514     /* Set stage 1 back to default */
9515     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9516     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9517     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9518     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9519     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9520     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9521     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9522     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9523     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9524     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9525 }
9526
9527 struct testdata
9528 {
9529     DWORD idxVertex; /* number of instances in the first stream */
9530     DWORD idxColor; /* number of instances in the second stream */
9531     DWORD idxInstance; /* should be 1 ?? */
9532     DWORD color1; /* color 1 instance */
9533     DWORD color2; /* color 2 instance */
9534     DWORD color3; /* color 3 instance */
9535     DWORD color4; /* color 4 instance */
9536     WORD strVertex; /* specify which stream to use 0-2*/
9537     WORD strColor;
9538     WORD strInstance;
9539 };
9540
9541 static const struct testdata testcases[]=
9542 {
9543     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9544     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9545     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9546     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9547     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  4 */
9548     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9549     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9550     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9551     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  8 */
9552     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /*  9 */
9553     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9554     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9555     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9556     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9557 /*
9558     This draws one instance on some machines, no instance on others
9559     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9560 */
9561 /*
9562     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9563     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9564 */
9565 };
9566
9567 /* Drawing Indexed Geometry with instances*/
9568 static void stream_test(IDirect3DDevice9 *device)
9569 {
9570     IDirect3DVertexBuffer9 *vb = NULL;
9571     IDirect3DVertexBuffer9 *vb2 = NULL;
9572     IDirect3DVertexBuffer9 *vb3 = NULL;
9573     IDirect3DIndexBuffer9 *ib = NULL;
9574     IDirect3DVertexDeclaration9 *pDecl = NULL;
9575     IDirect3DVertexShader9 *shader = NULL;
9576     HRESULT hr;
9577     BYTE *data;
9578     DWORD color;
9579     DWORD ind;
9580     unsigned i;
9581
9582     const DWORD shader_code[] =
9583     {
9584         0xfffe0101,                                     /* vs_1_1 */
9585         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9586         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9587         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9588         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9589         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9590         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9591         0x0000ffff
9592     };
9593
9594     const float quad[][3] =
9595     {
9596         {-0.5f, -0.5f,  1.1f}, /*0 */
9597         {-0.5f,  0.5f,  1.1f}, /*1 */
9598         { 0.5f, -0.5f,  1.1f}, /*2 */
9599         { 0.5f,  0.5f,  1.1f}, /*3 */
9600     };
9601
9602     const float vertcolor[][4] =
9603     {
9604         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9605         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9606         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9607         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9608     };
9609
9610     /* 4 position for 4 instances */
9611     const float instancepos[][3] =
9612     {
9613         {-0.6f,-0.6f, 0.0f},
9614         { 0.6f,-0.6f, 0.0f},
9615         { 0.6f, 0.6f, 0.0f},
9616         {-0.6f, 0.6f, 0.0f},
9617     };
9618
9619     short indices[] = {0, 1, 2, 1, 2, 3};
9620
9621     D3DVERTEXELEMENT9 decl[] =
9622     {
9623         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9624         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9625         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9626         D3DDECL_END()
9627     };
9628
9629     /* set the default value because it isn't done in wine? */
9630     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9631     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9632
9633     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9634     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9635     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9636
9637     /* check wrong cases */
9638     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9639     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9640     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9641     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9642     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9643     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9644     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9645     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9646     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9647     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9648     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9649     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9650     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9651     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9652     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9653     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9654     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9655     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9656     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9657     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9658
9659     /* set the default value back */
9660     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9661     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9662
9663     /* create all VertexBuffers*/
9664     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9665     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9666     if(!vb) {
9667         skip("Failed to create a vertex buffer\n");
9668         return;
9669     }
9670     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9671     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9672     if(!vb2) {
9673         skip("Failed to create a vertex buffer\n");
9674         goto out;
9675     }
9676     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9677     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9678     if(!vb3) {
9679         skip("Failed to create a vertex buffer\n");
9680         goto out;
9681     }
9682
9683     /* create IndexBuffer*/
9684     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9685     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9686     if(!ib) {
9687         skip("Failed to create a index buffer\n");
9688         goto out;
9689     }
9690
9691     /* copy all Buffers (Vertex + Index)*/
9692     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9693     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9694     memcpy(data, quad, sizeof(quad));
9695     hr = IDirect3DVertexBuffer9_Unlock(vb);
9696     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9697     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9698     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9699     memcpy(data, vertcolor, sizeof(vertcolor));
9700     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9701     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9702     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9703     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9704     memcpy(data, instancepos, sizeof(instancepos));
9705     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9706     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9707     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9708     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9709     memcpy(data, indices, sizeof(indices));
9710     hr = IDirect3DIndexBuffer9_Unlock(ib);
9711     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9712
9713     /* create VertexShader */
9714     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9715     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9716     if(!shader) {
9717         skip("Failed to create a vetex shader\n");
9718         goto out;
9719     }
9720
9721     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9722     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9723
9724     hr = IDirect3DDevice9_SetIndices(device, ib);
9725     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9726
9727     /* run all tests */
9728     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9729     {
9730         struct testdata act = testcases[i];
9731         decl[0].Stream = act.strVertex;
9732         decl[1].Stream = act.strColor;
9733         decl[2].Stream = act.strInstance;
9734         /* create VertexDeclarations */
9735         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9736         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9737
9738         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9739         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9740
9741         hr = IDirect3DDevice9_BeginScene(device);
9742         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9743         if(SUCCEEDED(hr))
9744         {
9745             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9746             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9747
9748             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9749             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9750             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9751             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9752
9753             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9754             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9755             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9756             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9757
9758             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9759             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9760             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9761             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9762
9763             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9764             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9765             hr = IDirect3DDevice9_EndScene(device);
9766             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9767
9768             /* set all StreamSource && StreamSourceFreq back to default */
9769             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9770             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9771             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9772             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9773             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9774             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9775             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9776             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9777             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9778             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9779             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9780             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9781         }
9782
9783         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9784         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9785
9786         color = getPixelColor(device, 160, 360);
9787         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9788         color = getPixelColor(device, 480, 360);
9789         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9790         color = getPixelColor(device, 480, 120);
9791         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9792         color = getPixelColor(device, 160, 120);
9793         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9794
9795         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9796         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9797     }
9798
9799     hr = IDirect3DDevice9_SetIndices(device, NULL);
9800     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9801
9802 out:
9803     if(vb) IDirect3DVertexBuffer9_Release(vb);
9804     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9805     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9806     if(ib)IDirect3DIndexBuffer9_Release(ib);
9807     if(shader)IDirect3DVertexShader9_Release(shader);
9808 }
9809
9810 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9811     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9812     IDirect3DTexture9 *dsttex = NULL;
9813     HRESULT hr;
9814     DWORD color;
9815     D3DRECT r1 = {0,  0,  50,  50 };
9816     D3DRECT r2 = {50, 0,  100, 50 };
9817     D3DRECT r3 = {50, 50, 100, 100};
9818     D3DRECT r4 = {0,  50,  50, 100};
9819     const float quad[] = {
9820         -1.0,   -1.0,   0.1,    0.0,    0.0,
9821          1.0,   -1.0,   0.1,    1.0,    0.0,
9822         -1.0,    1.0,   0.1,    0.0,    1.0,
9823          1.0,    1.0,   0.1,    1.0,    1.0,
9824     };
9825
9826     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9827     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9828
9829     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9830     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9831     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9832     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9833
9834     if(!src || !dsttex) {
9835         skip("One or more test resources could not be created\n");
9836         goto cleanup;
9837     }
9838
9839     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9840     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9841
9842     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9843     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9844
9845     /* Clear the StretchRect destination for debugging */
9846     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9847     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9848     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9849     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9850
9851     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9852     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9853
9854     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9855     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9856     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9857     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9858     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9859     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9860     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9861     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9862
9863     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9864      * the target -> texture GL blit path
9865      */
9866     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9867     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9868     IDirect3DSurface9_Release(dst);
9869
9870     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9871     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9872
9873     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9874     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9875     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9876     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9877     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9878     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9879     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9880     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9881
9882     hr = IDirect3DDevice9_BeginScene(device);
9883     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9884     if(SUCCEEDED(hr)) {
9885         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9886         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9887         hr = IDirect3DDevice9_EndScene(device);
9888         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9889     }
9890
9891     color = getPixelColor(device, 160, 360);
9892     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9893     color = getPixelColor(device, 480, 360);
9894     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9895     color = getPixelColor(device, 480, 120);
9896     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9897     color = getPixelColor(device, 160, 120);
9898     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9899     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9900     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9901
9902     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9903     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9904     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9905     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9906
9907 cleanup:
9908     if(src) IDirect3DSurface9_Release(src);
9909     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9910     if(dsttex) IDirect3DTexture9_Release(dsttex);
9911 }
9912
9913 static void texop_test(IDirect3DDevice9 *device)
9914 {
9915     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9916     IDirect3DTexture9 *texture = NULL;
9917     D3DLOCKED_RECT locked_rect;
9918     D3DCOLOR color;
9919     D3DCAPS9 caps;
9920     HRESULT hr;
9921     unsigned i;
9922
9923     static const struct {
9924         float x, y, z;
9925         float s, t;
9926         D3DCOLOR diffuse;
9927     } quad[] = {
9928         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9929         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9930         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9931         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9932     };
9933
9934     static const D3DVERTEXELEMENT9 decl_elements[] = {
9935         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9936         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9937         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9938         D3DDECL_END()
9939     };
9940
9941     static const struct {
9942         D3DTEXTUREOP op;
9943         const char *name;
9944         DWORD caps_flag;
9945         D3DCOLOR result;
9946     } test_data[] = {
9947         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9948         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9949         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9950         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9951         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9952         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9953         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9954         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9955         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9956         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9957         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9958         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9959         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9960         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9961         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9962         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9963         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9964         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9965         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9966         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9967         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9968         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9969         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9970     };
9971
9972     memset(&caps, 0, sizeof(caps));
9973     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9974     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9975
9976     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9977     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9978     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9979     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9980
9981     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9982     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9983     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9984     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9985     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9986     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9987     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9988     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9989     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9990
9991     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9992     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9993     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9994     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9995     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9996     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9997
9998     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9999     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10000
10001     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10002     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10003     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
10004     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10005     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
10006     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10007
10008     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10009     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10010
10011     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
10012     {
10013         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
10014         {
10015             skip("tex operation %s not supported\n", test_data[i].name);
10016             continue;
10017         }
10018
10019         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
10020         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
10021
10022         hr = IDirect3DDevice9_BeginScene(device);
10023         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10024
10025         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10026         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10027
10028         hr = IDirect3DDevice9_EndScene(device);
10029         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10030
10031         color = getPixelColor(device, 320, 240);
10032         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
10033                 test_data[i].name, color, test_data[i].result);
10034
10035         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10036         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10037     }
10038
10039     if (texture) IDirect3DTexture9_Release(texture);
10040     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
10041 }
10042
10043 static void yuv_color_test(IDirect3DDevice9 *device) {
10044     HRESULT hr;
10045     IDirect3DSurface9 *surface = NULL, *target = NULL;
10046     unsigned int fmt, i;
10047     D3DFORMAT format;
10048     const char *fmt_string;
10049     D3DLOCKED_RECT lr;
10050     IDirect3D9 *d3d;
10051     HRESULT color;
10052     DWORD ref_color_left, ref_color_right;
10053
10054     struct {
10055         DWORD in;           /* The input color */
10056         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
10057         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
10058         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
10059         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
10060     } test_data[] = {
10061     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
10062      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
10063      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
10064      * that
10065      */
10066       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
10067       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
10068       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
10069       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
10070       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
10071       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
10072       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
10073       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
10074       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
10075       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
10076       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
10077       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
10078       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
10079       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
10080
10081       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
10082       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
10083       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
10084       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
10085     };
10086
10087     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
10088     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
10089     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
10090     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
10091
10092     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
10093     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10094
10095     for(fmt = 0; fmt < 2; fmt++) {
10096         if(fmt == 0) {
10097             format = D3DFMT_UYVY;
10098             fmt_string = "D3DFMT_UYVY";
10099         } else {
10100             format = D3DFMT_YUY2;
10101             fmt_string = "D3DFMT_YUY2";
10102         }
10103
10104         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
10105                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
10106                        */
10107         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
10108                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
10109             skip("%s is not supported\n", fmt_string);
10110             continue;
10111         }
10112
10113         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
10114         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
10115         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
10116
10117         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
10118             if(fmt == 0) {
10119                 ref_color_left = test_data[i].uyvy_left;
10120                 ref_color_right = test_data[i].uyvy_right;
10121             } else {
10122                 ref_color_left = test_data[i].yuy2_left;
10123                 ref_color_right = test_data[i].yuy2_right;
10124             }
10125
10126             memset(&lr, 0, sizeof(lr));
10127             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
10128             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
10129             *((DWORD *) lr.pBits) = test_data[i].in;
10130             hr = IDirect3DSurface9_UnlockRect(surface);
10131             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10132
10133             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10134             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10135             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10136             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10137
10138             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10139              * prevent running into precision problems, read a far left and far right pixel. In the future we may
10140              * want to add tests for the filtered pixels as well.
10141              *
10142              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10143              * differently, so we need a max diff of 16
10144              */
10145             color = getPixelColor(device, 40, 240);
10146
10147             /* Newer versions of the Nvidia Windows driver mix up the U and V channels, breaking all the tests
10148              * where U != V. Skip the entire test if this bug in this case
10149              */
10150             if (broken(test_data[i].in == 0xff000000 && color == 0x00008800 && format == D3DFMT_UYVY))
10151             {
10152                 skip("Nvidia channel confusion bug detected, skipping YUV tests\n");
10153                 IDirect3DSurface9_Release(surface);
10154                 goto out;
10155             }
10156
10157             ok(color_match(color, ref_color_left, 18),
10158                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10159                test_data[i].in, color, ref_color_left, fmt_string);
10160             color = getPixelColor(device, 600, 240);
10161             ok(color_match(color, ref_color_right, 18),
10162                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10163                test_data[i].in, color, ref_color_right, fmt_string);
10164             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10165             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10166         }
10167         IDirect3DSurface9_Release(surface);
10168     }
10169
10170 out:
10171     IDirect3DSurface9_Release(target);
10172     IDirect3D9_Release(d3d);
10173 }
10174
10175 static void texop_range_test(IDirect3DDevice9 *device)
10176 {
10177     static const struct {
10178         float x, y, z;
10179         D3DCOLOR diffuse;
10180     } quad[] = {
10181         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10182         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10183         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10184         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10185     };
10186     HRESULT hr;
10187     IDirect3DTexture9 *texture;
10188     D3DLOCKED_RECT locked_rect;
10189     D3DCAPS9 caps;
10190     DWORD color;
10191
10192     /* We need ADD and SUBTRACT operations */
10193     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10194     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10195     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10196         skip("D3DTOP_ADD is not supported, skipping value range test\n");
10197         return;
10198     }
10199     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10200         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10201         return;
10202     }
10203
10204     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10205     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10206     /* Stage 1: result = diffuse(=1.0) + diffuse
10207      * stage 2: result = result - tfactor(= 0.5)
10208      */
10209     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10210     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10211     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10212     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10213     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10214     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10215     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10216     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10217     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10218     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10219     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10220     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10221     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10222     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10223
10224     hr = IDirect3DDevice9_BeginScene(device);
10225     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10226     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10227     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10228     hr = IDirect3DDevice9_EndScene(device);
10229     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10230
10231     color = getPixelColor(device, 320, 240);
10232     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10233        color);
10234     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10235     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10236
10237     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10238     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10239     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10240     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10241     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10242     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10243     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10244     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10245     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10246
10247     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10248      * stage 2: result = result + diffuse(1.0)
10249      */
10250     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10251     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10252     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10253     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10254     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10255     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10256     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10257     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10258     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10259     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10260     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10261     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10262     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10263     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10264
10265     hr = IDirect3DDevice9_BeginScene(device);
10266     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10267     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10268     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10269     hr = IDirect3DDevice9_EndScene(device);
10270     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10271
10272     color = getPixelColor(device, 320, 240);
10273     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10274        color);
10275     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10276     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10277
10278     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10279     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10280     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10281     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10282     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10283     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10284     IDirect3DTexture9_Release(texture);
10285 }
10286
10287 static void alphareplicate_test(IDirect3DDevice9 *device) {
10288     struct vertex quad[] = {
10289         { -1.0,    -1.0,    0.1,    0x80ff00ff },
10290         {  1.0,    -1.0,    0.1,    0x80ff00ff },
10291         { -1.0,     1.0,    0.1,    0x80ff00ff },
10292         {  1.0,     1.0,    0.1,    0x80ff00ff },
10293     };
10294     HRESULT hr;
10295     DWORD color;
10296
10297     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10298     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10299
10300     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10301     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10302
10303     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10304     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10305     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10306     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10307
10308     hr = IDirect3DDevice9_BeginScene(device);
10309     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10310     if(SUCCEEDED(hr)) {
10311         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10312         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10313         hr = IDirect3DDevice9_EndScene(device);
10314         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10315     }
10316
10317     color = getPixelColor(device, 320, 240);
10318     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10319        color);
10320     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10321     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10322
10323     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10324     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10325
10326 }
10327
10328 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10329     HRESULT hr;
10330     D3DCAPS9 caps;
10331     DWORD color;
10332     struct vertex quad[] = {
10333         { -1.0,    -1.0,    0.1,    0x408080c0 },
10334         {  1.0,    -1.0,    0.1,    0x408080c0 },
10335         { -1.0,     1.0,    0.1,    0x408080c0 },
10336         {  1.0,     1.0,    0.1,    0x408080c0 },
10337     };
10338
10339     memset(&caps, 0, sizeof(caps));
10340     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10341     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10342     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10343         skip("D3DTOP_DOTPRODUCT3 not supported\n");
10344         return;
10345     }
10346
10347     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10348     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10349
10350     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10351     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10352
10353     /* dp3_x4 r0, diffuse_bias, tfactor_bias
10354      * mov r0.a, diffuse.a
10355      * mov r0, r0.a
10356      *
10357      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10358      * 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
10359      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10360      */
10361     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10362     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10363     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10364     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10365     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10366     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10367     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10368     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10369     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10370     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10371     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10372     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10373     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10374     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10375     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10376     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10377     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10378     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10379
10380     hr = IDirect3DDevice9_BeginScene(device);
10381     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10382     if(SUCCEEDED(hr)) {
10383         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10384         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10385         hr = IDirect3DDevice9_EndScene(device);
10386         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10387     }
10388
10389     color = getPixelColor(device, 320, 240);
10390     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10391        color);
10392     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10393     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10394
10395     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10396     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10397     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10398     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10399     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10400     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10401 }
10402
10403 static void zwriteenable_test(IDirect3DDevice9 *device) {
10404     HRESULT hr;
10405     DWORD color;
10406     struct vertex quad1[] = {
10407         { -1.0,  -1.0,  0.1,    0x00ff0000},
10408         { -1.0,   1.0,  0.1,    0x00ff0000},
10409         {  1.0,  -1.0,  0.1,    0x00ff0000},
10410         {  1.0,   1.0,  0.1,    0x00ff0000},
10411     };
10412     struct vertex quad2[] = {
10413         { -1.0,  -1.0,  0.9,    0x0000ff00},
10414         { -1.0,   1.0,  0.9,    0x0000ff00},
10415         {  1.0,  -1.0,  0.9,    0x0000ff00},
10416         {  1.0,   1.0,  0.9,    0x0000ff00},
10417     };
10418
10419     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10420     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10421
10422     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10423     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10424     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10425     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10426     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10427     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10428     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10429     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10430
10431     hr = IDirect3DDevice9_BeginScene(device);
10432     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10433     if(SUCCEEDED(hr)) {
10434         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10435          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10436          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10437          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10438          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10439          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10440          */
10441         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10442         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10443         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10444         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10445         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10446         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10447
10448         hr = IDirect3DDevice9_EndScene(device);
10449         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10450     }
10451
10452     color = getPixelColor(device, 320, 240);
10453     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10454        color);
10455     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10456     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10457
10458     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10459     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10460 }
10461
10462 static void alphatest_test(IDirect3DDevice9 *device) {
10463 #define ALPHATEST_PASSED 0x0000ff00
10464 #define ALPHATEST_FAILED 0x00ff0000
10465     struct {
10466         D3DCMPFUNC  func;
10467         DWORD       color_less;
10468         DWORD       color_equal;
10469         DWORD       color_greater;
10470     } testdata[] = {
10471         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10472         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10473         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10474         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10475         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10476         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10477         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10478         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10479     };
10480     unsigned int i, j;
10481     HRESULT hr;
10482     DWORD color;
10483     struct vertex quad[] = {
10484         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10485         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10486         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10487         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10488     };
10489     D3DCAPS9 caps;
10490
10491     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10492     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10493     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10494     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10495
10496     for(j = 0; j < 2; j++) {
10497         if(j == 1) {
10498             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10499              * the alpha test either for performance reasons(floating point RTs) or to work
10500              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10501              * codepath for ffp and shader in this case, and the test should cover both
10502              */
10503             IDirect3DPixelShader9 *ps;
10504             DWORD shader_code[] = {
10505                 0xffff0101,                                 /* ps_1_1           */
10506                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10507                 0x0000ffff                                  /* end              */
10508             };
10509             memset(&caps, 0, sizeof(caps));
10510             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10511             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10512             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10513                 break;
10514             }
10515
10516             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10517             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10518             IDirect3DDevice9_SetPixelShader(device, ps);
10519             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10520             IDirect3DPixelShader9_Release(ps);
10521         }
10522
10523         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10524             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10525             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10526
10527             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10528             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10529             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10530             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10531             hr = IDirect3DDevice9_BeginScene(device);
10532             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10533             if(SUCCEEDED(hr)) {
10534                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10535                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10536                 hr = IDirect3DDevice9_EndScene(device);
10537                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10538             }
10539             color = getPixelColor(device, 320, 240);
10540             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10541             color, testdata[i].color_less, testdata[i].func);
10542             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10543             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10544
10545             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10546             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10547             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10548             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10549             hr = IDirect3DDevice9_BeginScene(device);
10550             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10551             if(SUCCEEDED(hr)) {
10552                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10553                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10554                 hr = IDirect3DDevice9_EndScene(device);
10555                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10556             }
10557             color = getPixelColor(device, 320, 240);
10558             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10559             color, testdata[i].color_equal, testdata[i].func);
10560             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10561             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10562
10563             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10564             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10565             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10566             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10567             hr = IDirect3DDevice9_BeginScene(device);
10568             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10569             if(SUCCEEDED(hr)) {
10570                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10571                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10572                 hr = IDirect3DDevice9_EndScene(device);
10573                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10574             }
10575             color = getPixelColor(device, 320, 240);
10576             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10577             color, testdata[i].color_greater, testdata[i].func);
10578             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10579             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10580         }
10581     }
10582
10583     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10584     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10585     IDirect3DDevice9_SetPixelShader(device, NULL);
10586     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10587 }
10588
10589 static void sincos_test(IDirect3DDevice9 *device) {
10590     const DWORD sin_shader_code[] = {
10591         0xfffe0200,                                                                 /* vs_2_0                       */
10592         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10593         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10594         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10595         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10596         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10597         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10598         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10599         0x0000ffff                                                                  /* end                          */
10600     };
10601     const DWORD cos_shader_code[] = {
10602         0xfffe0200,                                                                 /* vs_2_0                       */
10603         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10604         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10605         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10606         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10607         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10608         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10609         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10610         0x0000ffff                                                                  /* end                          */
10611     };
10612     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10613     HRESULT hr;
10614     struct {
10615         float x, y, z;
10616     } data[1280];
10617     unsigned int i;
10618     float sincosc1[4] = {D3DSINCOSCONST1};
10619     float sincosc2[4] = {D3DSINCOSCONST2};
10620
10621     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10622     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10623
10624     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10625     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10626     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10627     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10628     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10629     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10630     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10631     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10632     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10633     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10634
10635     /* Generate a point from -1 to 1 every 0.5 pixels */
10636     for(i = 0; i < 1280; i++) {
10637         data[i].x = (-640.0 + i) / 640.0;
10638         data[i].y = 0.0;
10639         data[i].z = 0.1;
10640     }
10641
10642     hr = IDirect3DDevice9_BeginScene(device);
10643     if(SUCCEEDED(hr)) {
10644         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10645         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10646         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10647         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10648
10649         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10650         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10651         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10652         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10653
10654         hr = IDirect3DDevice9_EndScene(device);
10655         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10656     }
10657     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10658     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10659     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10660
10661     IDirect3DDevice9_SetVertexShader(device, NULL);
10662     IDirect3DVertexShader9_Release(sin_shader);
10663     IDirect3DVertexShader9_Release(cos_shader);
10664 }
10665
10666 static void loop_index_test(IDirect3DDevice9 *device) {
10667     const DWORD shader_code[] = {
10668         0xfffe0200,                                                 /* vs_2_0                   */
10669         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10670         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10671         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10672         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10673         0x0000001d,                                                 /* endloop                  */
10674         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10675         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10676         0x0000ffff                                                  /* END                      */
10677     };
10678     IDirect3DVertexShader9 *shader;
10679     HRESULT hr;
10680     DWORD color;
10681     const float quad[] = {
10682         -1.0,   -1.0,   0.1,
10683          1.0,   -1.0,   0.1,
10684         -1.0,    1.0,   0.1,
10685          1.0,    1.0,   0.1
10686     };
10687     const float zero[4] = {0, 0, 0, 0};
10688     const float one[4] = {1, 1, 1, 1};
10689     int i0[4] = {2, 10, -3, 0};
10690     float values[4];
10691
10692     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10693     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10694     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10695     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10696     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10697     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10698     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10699     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10700
10701     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10702     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10703     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10704     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10705     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10706     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10707     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10708     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10709     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10710     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10711     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10712     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10713     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10714     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10715     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10716     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10717     values[0] = 1.0;
10718     values[1] = 1.0;
10719     values[2] = 0.0;
10720     values[3] = 0.0;
10721     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10722     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10723     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10724     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10725     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10726     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10727     values[0] = -1.0;
10728     values[1] = 0.0;
10729     values[2] = 0.0;
10730     values[3] = 0.0;
10731     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10732     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10733     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10734     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10735     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10736     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10737     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10738     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10739     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10740     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10741
10742     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10743     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10744
10745     hr = IDirect3DDevice9_BeginScene(device);
10746     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10747     if(SUCCEEDED(hr))
10748     {
10749         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10750         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10751         hr = IDirect3DDevice9_EndScene(device);
10752         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10753     }
10754     color = getPixelColor(device, 320, 240);
10755     ok(color_match(color, 0x0000ff00, 1),
10756        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10757     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10758     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10759
10760     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10761     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10762     IDirect3DVertexShader9_Release(shader);
10763 }
10764
10765 static void sgn_test(IDirect3DDevice9 *device) {
10766     const DWORD shader_code[] = {
10767         0xfffe0200,                                                             /* vs_2_0                       */
10768         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10769         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10770         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10771         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10772         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10773         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10774         0x0000ffff                                                              /* end                          */
10775     };
10776     IDirect3DVertexShader9 *shader;
10777     HRESULT hr;
10778     DWORD color;
10779     const float quad[] = {
10780         -1.0,   -1.0,   0.1,
10781          1.0,   -1.0,   0.1,
10782         -1.0,    1.0,   0.1,
10783          1.0,    1.0,   0.1
10784     };
10785
10786     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10787     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10788     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10789     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10790     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10791     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10792     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10793     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10794
10795     hr = IDirect3DDevice9_BeginScene(device);
10796     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10797     if(SUCCEEDED(hr))
10798     {
10799         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10800         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10801         hr = IDirect3DDevice9_EndScene(device);
10802         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10803     }
10804     color = getPixelColor(device, 320, 240);
10805     ok(color_match(color, 0x008000ff, 1),
10806        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10807     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10808     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10809
10810     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10811     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10812     IDirect3DVertexShader9_Release(shader);
10813 }
10814
10815 static void viewport_test(IDirect3DDevice9 *device) {
10816     HRESULT hr;
10817     DWORD color;
10818     D3DVIEWPORT9 vp, old_vp;
10819     BOOL draw_failed = TRUE;
10820     const float quad[] =
10821     {
10822         -0.5,   -0.5,   0.1,
10823          0.5,   -0.5,   0.1,
10824         -0.5,    0.5,   0.1,
10825          0.5,    0.5,   0.1
10826     };
10827
10828     memset(&old_vp, 0, sizeof(old_vp));
10829     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10830     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10831
10832     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10833     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10834
10835     /* Test a viewport with Width and Height bigger than the surface dimensions
10836      *
10837      * TODO: Test Width < surface.width, but X + Width > surface.width
10838      * TODO: Test Width < surface.width, what happens with the height?
10839      *
10840      * The expected behavior is that the viewport behaves like the "default"
10841      * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
10842      * MinZ = 0.0, MaxZ = 1.0.
10843      *
10844      * Starting with Windows 7 the behavior among driver versions is not
10845      * consistent. The SetViewport call is accepted on all drivers. Some
10846      * drivers(older nvidia ones) refuse to draw and return an error. Newer
10847      * nvidia drivers draw, but use the actual values in the viewport and only
10848      * display the upper left part on the surface.
10849      */
10850     memset(&vp, 0, sizeof(vp));
10851     vp.X = 0;
10852     vp.Y = 0;
10853     vp.Width = 10000;
10854     vp.Height = 10000;
10855     vp.MinZ = 0.0;
10856     vp.MaxZ = 0.0;
10857     hr = IDirect3DDevice9_SetViewport(device, &vp);
10858     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10859
10860     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10861     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10862     hr = IDirect3DDevice9_BeginScene(device);
10863     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10864     if(SUCCEEDED(hr))
10865     {
10866         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10867         ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10868         draw_failed = FAILED(hr);
10869         hr = IDirect3DDevice9_EndScene(device);
10870         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10871     }
10872
10873     if(!draw_failed)
10874     {
10875         color = getPixelColor(device, 158, 118);
10876         ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10877         color = getPixelColor(device, 162, 118);
10878         ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10879         color = getPixelColor(device, 158, 122);
10880         ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10881         color = getPixelColor(device, 162, 122);
10882         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
10883
10884         color = getPixelColor(device, 478, 358);
10885         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
10886         color = getPixelColor(device, 482, 358);
10887         ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10888         color = getPixelColor(device, 478, 362);
10889         ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10890         color = getPixelColor(device, 482, 362);
10891         ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10892     }
10893
10894     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10895     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10896
10897     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10898     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10899 }
10900
10901 /* This test tests depth clamping / clipping behaviour:
10902  *   - With software vertex processing, depth values are clamped to the
10903  *     minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
10904  *     when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
10905  *     same as regular vertices here.
10906  *   - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
10907  *     Normal vertices are always clipped. Pretransformed vertices are
10908  *     clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
10909  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10910  */
10911 static void depth_clamp_test(IDirect3DDevice9 *device)
10912 {
10913     const struct tvertex quad1[] =
10914     {
10915         {  0.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
10916         {640.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
10917         {  0.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
10918         {640.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
10919     };
10920     const struct tvertex quad2[] =
10921     {
10922         {  0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10923         {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10924         {  0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10925         {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10926     };
10927     const struct tvertex quad3[] =
10928     {
10929         {112.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
10930         {208.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
10931         {112.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
10932         {208.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
10933     };
10934     const struct tvertex quad4[] =
10935     {
10936         { 42.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
10937         {112.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
10938         { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10939         {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10940     };
10941     const struct vertex quad5[] =
10942     {
10943         { -0.5f,   0.5f, 10.0f,       0xff14f914},
10944         {  0.5f,   0.5f, 10.0f,       0xff14f914},
10945         { -0.5f,  -0.5f, 10.0f,       0xff14f914},
10946         {  0.5f,  -0.5f, 10.0f,       0xff14f914},
10947     };
10948     const struct vertex quad6[] =
10949     {
10950         { -1.0f,   0.5f, 10.0f,      0xfff91414},
10951         {  1.0f,   0.5f, 10.0f,      0xfff91414},
10952         { -1.0f,  0.25f, 10.0f,      0xfff91414},
10953         {  1.0f,  0.25f, 10.0f,      0xfff91414},
10954     };
10955
10956     D3DVIEWPORT9 vp;
10957     D3DCOLOR color;
10958     D3DCAPS9 caps;
10959     HRESULT hr;
10960
10961     vp.X = 0;
10962     vp.Y = 0;
10963     vp.Width = 640;
10964     vp.Height = 480;
10965     vp.MinZ = 0.0;
10966     vp.MaxZ = 7.5;
10967
10968     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10969     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10970
10971     hr = IDirect3DDevice9_SetViewport(device, &vp);
10972     if(FAILED(hr))
10973     {
10974         /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10975          * the tests because the 7.5 is just intended to show that it doesn't have
10976          * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10977          * viewport and continue.
10978          */
10979         ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10980         vp.MaxZ = 1.0;
10981         hr = IDirect3DDevice9_SetViewport(device, &vp);
10982     }
10983     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10984
10985     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
10986     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10987
10988     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10989     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10990     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10991     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10992     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10993     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10994     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10995     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10996
10997     hr = IDirect3DDevice9_BeginScene(device);
10998     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10999
11000     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11001     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11002
11003     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11004     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11005     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11006     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11007
11008     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11009     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11010
11011     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11012     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11013     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
11014     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11015
11016     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
11017     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11018
11019     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11020     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11021
11022     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
11023     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11024
11025     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11026     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11027
11028     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
11029     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11030
11031     hr = IDirect3DDevice9_EndScene(device);
11032     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11033
11034     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
11035     {
11036         color = getPixelColor(device, 75, 75);
11037         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11038         color = getPixelColor(device, 150, 150);
11039         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11040         color = getPixelColor(device, 320, 240);
11041         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11042         color = getPixelColor(device, 320, 330);
11043         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11044         color = getPixelColor(device, 320, 330);
11045         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11046     }
11047     else
11048     {
11049         color = getPixelColor(device, 75, 75);
11050         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11051         color = getPixelColor(device, 150, 150);
11052         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11053         color = getPixelColor(device, 320, 240);
11054         ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11055         color = getPixelColor(device, 320, 330);
11056         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11057         color = getPixelColor(device, 320, 330);
11058         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11059     }
11060
11061     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11062     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11063
11064     vp.MinZ = 0.0;
11065     vp.MaxZ = 1.0;
11066     hr = IDirect3DDevice9_SetViewport(device, &vp);
11067     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11068 }
11069
11070 static void depth_bounds_test(IDirect3DDevice9 *device)
11071 {
11072     const struct tvertex quad1[] =
11073     {
11074         {    0,    0, 0.0f, 1, 0xfff9e814},
11075         {  640,    0, 0.0f, 1, 0xfff9e814},
11076         {    0,  480, 1.0f, 1, 0xfff9e814},
11077         {  640,  480, 1.0f, 1, 0xfff9e814},
11078     };
11079     const struct tvertex quad2[] =
11080     {
11081         {    0,    0,  0.6f, 1, 0xff002b7f},
11082         {  640,    0,  0.6f, 1, 0xff002b7f},
11083         {    0,  480,  0.6f, 1, 0xff002b7f},
11084         {  640,  480,  0.6f, 1, 0xff002b7f},
11085     };
11086     const struct tvertex quad3[] =
11087     {
11088         {    0,  100, 0.6f, 1, 0xfff91414},
11089         {  640,  100, 0.6f, 1, 0xfff91414},
11090         {    0,  160, 0.6f, 1, 0xfff91414},
11091         {  640,  160, 0.6f, 1, 0xfff91414},
11092     };
11093
11094     union {
11095         DWORD d;
11096         float f;
11097     } tmpvalue;
11098
11099     IDirect3D9 *d3d = NULL;
11100     IDirect3DSurface9 *offscreen_surface = NULL;
11101     D3DCOLOR color;
11102     HRESULT hr;
11103
11104     IDirect3DDevice9_GetDirect3D(device, &d3d);
11105     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11106             0,  D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
11107         skip("No NVDB (depth bounds test) support\n");
11108         IDirect3D9_Release(d3d);
11109         return;
11110     }
11111     IDirect3D9_Release(d3d);
11112
11113     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
11114             MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
11115     ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
11116     if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
11117
11118     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
11119     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11120
11121     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11122     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11123     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
11124     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11125     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11126     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11127     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11128     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11129
11130
11131     hr = IDirect3DDevice9_BeginScene(device);
11132     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11133
11134     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11135     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11136
11137     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11138     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11139
11140     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
11141     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11142
11143     tmpvalue.f = 0.625;
11144     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11145     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11146
11147     tmpvalue.f = 0.75;
11148     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
11149     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11150
11151     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11152     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11153
11154     tmpvalue.f = 0.75;
11155     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11156     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11157
11158     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11159     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11160
11161     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
11162     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11163
11164     hr = IDirect3DDevice9_EndScene(device);
11165     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11166
11167     color = getPixelColor(device, 150, 130);
11168     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11169     color = getPixelColor(device, 150, 200);
11170     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11171     color = getPixelColor(device, 150, 300-5);
11172     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11173     color = getPixelColor(device, 150, 300+5);
11174     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11175     color = getPixelColor(device, 150, 330);
11176     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11177     color = getPixelColor(device, 150, 360-5);
11178     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11179     color = getPixelColor(device, 150, 360+5);
11180     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11181
11182     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11183     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11184 }
11185
11186 static void depth_buffer_test(IDirect3DDevice9 *device)
11187 {
11188     static const struct vertex quad1[] =
11189     {
11190         { -1.0,  1.0, 0.33f, 0xff00ff00},
11191         {  1.0,  1.0, 0.33f, 0xff00ff00},
11192         { -1.0, -1.0, 0.33f, 0xff00ff00},
11193         {  1.0, -1.0, 0.33f, 0xff00ff00},
11194     };
11195     static const struct vertex quad2[] =
11196     {
11197         { -1.0,  1.0, 0.50f, 0xffff00ff},
11198         {  1.0,  1.0, 0.50f, 0xffff00ff},
11199         { -1.0, -1.0, 0.50f, 0xffff00ff},
11200         {  1.0, -1.0, 0.50f, 0xffff00ff},
11201     };
11202     static const struct vertex quad3[] =
11203     {
11204         { -1.0,  1.0, 0.66f, 0xffff0000},
11205         {  1.0,  1.0, 0.66f, 0xffff0000},
11206         { -1.0, -1.0, 0.66f, 0xffff0000},
11207         {  1.0, -1.0, 0.66f, 0xffff0000},
11208     };
11209     static const DWORD expected_colors[4][4] =
11210     {
11211         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11212         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11213         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11214         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11215     };
11216
11217     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
11218     unsigned int i, j;
11219     D3DVIEWPORT9 vp;
11220     D3DCOLOR color;
11221     HRESULT hr;
11222
11223     vp.X = 0;
11224     vp.Y = 0;
11225     vp.Width = 640;
11226     vp.Height = 480;
11227     vp.MinZ = 0.0;
11228     vp.MaxZ = 1.0;
11229
11230     hr = IDirect3DDevice9_SetViewport(device, &vp);
11231     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11232
11233     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11234     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11235     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11236     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11237     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11238     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11239     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11240     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11241     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11242     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11243
11244     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11245     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11246     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
11247             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11248     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11249     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11250             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11251     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11252     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11253             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
11254     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11255
11256     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11257     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11258     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11259     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11260
11261     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11262     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11263     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11264     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11265
11266     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11267     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11268     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11269     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11270
11271     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11272     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11273     hr = IDirect3DDevice9_BeginScene(device);
11274     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11275     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11276     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11277     hr = IDirect3DDevice9_EndScene(device);
11278     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11279
11280     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11281     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11282     IDirect3DSurface9_Release(backbuffer);
11283     IDirect3DSurface9_Release(rt3);
11284     IDirect3DSurface9_Release(rt2);
11285     IDirect3DSurface9_Release(rt1);
11286
11287     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11288     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11289
11290     hr = IDirect3DDevice9_BeginScene(device);
11291     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11292     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11293     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11294     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11295     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11296     hr = IDirect3DDevice9_EndScene(device);
11297     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11298
11299     for (i = 0; i < 4; ++i)
11300     {
11301         for (j = 0; j < 4; ++j)
11302         {
11303             unsigned int x = 80 * ((2 * j) + 1);
11304             unsigned int y = 60 * ((2 * i) + 1);
11305             color = getPixelColor(device, x, y);
11306             ok(color_match(color, expected_colors[i][j], 0),
11307                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11308         }
11309     }
11310
11311     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11312     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11313 }
11314
11315 /* Test that partial depth copies work the way they're supposed to. The clear
11316  * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
11317  * the following draw should only copy back the part that was modified. */
11318 static void depth_buffer2_test(IDirect3DDevice9 *device)
11319 {
11320     static const struct vertex quad[] =
11321     {
11322         { -1.0,  1.0, 0.66f, 0xffff0000},
11323         {  1.0,  1.0, 0.66f, 0xffff0000},
11324         { -1.0, -1.0, 0.66f, 0xffff0000},
11325         {  1.0, -1.0, 0.66f, 0xffff0000},
11326     };
11327
11328     IDirect3DSurface9 *backbuffer, *rt1, *rt2;
11329     unsigned int i, j;
11330     D3DVIEWPORT9 vp;
11331     D3DCOLOR color;
11332     HRESULT hr;
11333
11334     vp.X = 0;
11335     vp.Y = 0;
11336     vp.Width = 640;
11337     vp.Height = 480;
11338     vp.MinZ = 0.0;
11339     vp.MaxZ = 1.0;
11340
11341     hr = IDirect3DDevice9_SetViewport(device, &vp);
11342     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11343
11344     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11345     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11346     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11347     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11348     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11349     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11350     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11351     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11352     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11353     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11354
11355     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11356             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11357     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11358     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11359             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11360     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11361     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11362     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11363
11364     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11365     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11366     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11367     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11368
11369     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11370     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11371     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
11372     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11373
11374     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11375     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11376     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11377     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11378
11379     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11380     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11381     IDirect3DSurface9_Release(backbuffer);
11382     IDirect3DSurface9_Release(rt2);
11383     IDirect3DSurface9_Release(rt1);
11384
11385     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11386     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11387
11388     hr = IDirect3DDevice9_BeginScene(device);
11389     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11390     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11391     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11392     hr = IDirect3DDevice9_EndScene(device);
11393     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11394
11395     for (i = 0; i < 4; ++i)
11396     {
11397         for (j = 0; j < 4; ++j)
11398         {
11399             unsigned int x = 80 * ((2 * j) + 1);
11400             unsigned int y = 60 * ((2 * i) + 1);
11401             color = getPixelColor(device, x, y);
11402             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11403                     "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
11404         }
11405     }
11406
11407     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11408     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11409 }
11410
11411 static void depth_blit_test(IDirect3DDevice9 *device)
11412 {
11413     static const struct vertex quad1[] =
11414     {
11415         { -1.0,  1.0, 0.50f, 0xff00ff00},
11416         {  1.0,  1.0, 0.50f, 0xff00ff00},
11417         { -1.0, -1.0, 0.50f, 0xff00ff00},
11418         {  1.0, -1.0, 0.50f, 0xff00ff00},
11419     };
11420     static const struct vertex quad2[] =
11421     {
11422         { -1.0,  1.0, 0.66f, 0xff0000ff},
11423         {  1.0,  1.0, 0.66f, 0xff0000ff},
11424         { -1.0, -1.0, 0.66f, 0xff0000ff},
11425         {  1.0, -1.0, 0.66f, 0xff0000ff},
11426     };
11427     static const DWORD expected_colors[4][4] =
11428     {
11429         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11430         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11431         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11432         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11433     };
11434
11435     IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
11436     RECT src_rect, dst_rect;
11437     unsigned int i, j;
11438     D3DVIEWPORT9 vp;
11439     D3DCOLOR color;
11440     HRESULT hr;
11441
11442     vp.X = 0;
11443     vp.Y = 0;
11444     vp.Width = 640;
11445     vp.Height = 480;
11446     vp.MinZ = 0.0;
11447     vp.MaxZ = 1.0;
11448
11449     hr = IDirect3DDevice9_SetViewport(device, &vp);
11450     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11451
11452     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11453     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11454     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11455     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11456     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11457     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11458     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11459     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11460     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
11461     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11462
11463     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11464     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11465     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11466     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11467     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11468     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11469     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11470     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11471
11472     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11473     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11474     SetRect(&dst_rect, 0, 0, 480, 360);
11475     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11476     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11477     SetRect(&dst_rect, 0, 0, 320, 240);
11478     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11479     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11480
11481     /* Partial blit. */
11482     SetRect(&src_rect, 0, 0, 320, 240);
11483     SetRect(&dst_rect, 0, 0, 320, 240);
11484     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11485     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11486     /* Flipped. */
11487     SetRect(&src_rect, 0, 0, 640, 480);
11488     SetRect(&dst_rect, 0, 480, 640, 0);
11489     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11490     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11491     /* Full, explicit. */
11492     SetRect(&src_rect, 0, 0, 640, 480);
11493     SetRect(&dst_rect, 0, 0, 640, 480);
11494     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11495     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11496     /* Filtered blit. */
11497     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11498     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11499     /* Depth -> color blit.*/
11500     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11501     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11502     IDirect3DSurface9_Release(backbuffer);
11503     /* Full surface, different sizes */
11504     hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
11505     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11506     hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
11507     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11508
11509     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11510     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11511     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11512     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11513     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11514     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11515     IDirect3DSurface9_Release(ds3);
11516     IDirect3DSurface9_Release(ds2);
11517     IDirect3DSurface9_Release(ds1);
11518
11519     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11520     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11521     hr = IDirect3DDevice9_BeginScene(device);
11522     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11523     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11524     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11525     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11526     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11527     hr = IDirect3DDevice9_EndScene(device);
11528     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11529
11530     for (i = 0; i < 4; ++i)
11531     {
11532         for (j = 0; j < 4; ++j)
11533         {
11534             unsigned int x = 80 * ((2 * j) + 1);
11535             unsigned int y = 60 * ((2 * i) + 1);
11536             color = getPixelColor(device, x, y);
11537             ok(color_match(color, expected_colors[i][j], 0),
11538                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11539         }
11540     }
11541
11542     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11543     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11544 }
11545
11546 static void intz_test(IDirect3DDevice9 *device)
11547 {
11548     static const DWORD ps_code[] =
11549     {
11550         0xffff0200,                                                             /* ps_2_0                       */
11551         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11552         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11553         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11554         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11555         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11556         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11557         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11558         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11559         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
11560         0x0000ffff,                                                             /* end                          */
11561     };
11562     struct
11563     {
11564         float x, y, z;
11565         float s, t, p, q;
11566     }
11567     quad[] =
11568     {
11569         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11570         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11571         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11572         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11573     },
11574     half_quad_1[] =
11575     {
11576         { -1.0f,  0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11577         {  1.0f,  0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11578         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11579         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11580     },
11581     half_quad_2[] =
11582     {
11583         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11584         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11585         { -1.0f,  0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11586         {  1.0f,  0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11587     };
11588     struct
11589     {
11590         UINT x, y;
11591         D3DCOLOR color;
11592     }
11593     expected_colors[] =
11594     {
11595         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11596         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11597         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11598         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11599         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11600         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11601         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11602         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11603     };
11604
11605     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11606     IDirect3DTexture9 *texture;
11607     IDirect3DPixelShader9 *ps;
11608     IDirect3DSurface9 *ds;
11609     IDirect3D9 *d3d9;
11610     D3DCAPS9 caps;
11611     HRESULT hr;
11612     UINT i;
11613
11614     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11615     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11616     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11617     {
11618         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11619         return;
11620     }
11621     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
11622     {
11623         skip("No unconditional NP2 texture support, skipping INTZ test.\n");
11624         return;
11625     }
11626
11627     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11628     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11629
11630     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11631             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11632     if (FAILED(hr))
11633     {
11634         skip("No INTZ support, skipping INTZ test.\n");
11635         return;
11636     }
11637
11638     IDirect3D9_Release(d3d9);
11639
11640     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11641     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11642     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11643     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11644
11645     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11646             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11647     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11648     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11649             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11650     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11651     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11652     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11653
11654     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11655     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11656     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11657     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11658     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11659     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11660     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11661     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11662     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11663     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11664
11665     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11666     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11667     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11668     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11669     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11670     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11671     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11672     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11673     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11674     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11675
11676     /* Render offscreen, using the INTZ texture as depth buffer */
11677     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11678     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11679     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11680     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11681     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11682     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11683     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11684     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11685
11686     /* Setup the depth/stencil surface. */
11687     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11688     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11689
11690     hr = IDirect3DDevice9_BeginScene(device);
11691     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11692     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11693     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11694     hr = IDirect3DDevice9_EndScene(device);
11695     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11696
11697     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11698     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11699     IDirect3DSurface9_Release(ds);
11700     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11701     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11702     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11703     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11704     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11705     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11706
11707     /* Read the depth values back. */
11708     hr = IDirect3DDevice9_BeginScene(device);
11709     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11710     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11711     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11712     hr = IDirect3DDevice9_EndScene(device);
11713     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11714
11715     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11716     {
11717         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11718         ok(color_match(color, expected_colors[i].color, 1),
11719                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11720                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11721     }
11722
11723     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11724     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11725
11726     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11727     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11728     IDirect3DTexture9_Release(texture);
11729
11730     /* Render onscreen while using the INTZ texture as depth buffer */
11731     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11732             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11733     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11734     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11735     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11736     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11737     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11738     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11739
11740     /* Setup the depth/stencil surface. */
11741     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11742     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11743
11744     hr = IDirect3DDevice9_BeginScene(device);
11745     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11746     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11747     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11748     hr = IDirect3DDevice9_EndScene(device);
11749     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11750
11751     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11752     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11753     IDirect3DSurface9_Release(ds);
11754     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11755     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11756     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11757     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11758
11759     /* Read the depth values back. */
11760     hr = IDirect3DDevice9_BeginScene(device);
11761     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11762     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11763     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11764     hr = IDirect3DDevice9_EndScene(device);
11765     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11766
11767     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11768     {
11769         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11770         ok(color_match(color, expected_colors[i].color, 1),
11771                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11772                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11773     }
11774
11775     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11776     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11777
11778     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11779     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11780     IDirect3DTexture9_Release(texture);
11781
11782     /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
11783     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11784             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11785     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11786     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11787
11788     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11789     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11790     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11791     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11792     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11793     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11794
11795     /* Setup the depth/stencil surface. */
11796     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11797     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11798
11799     hr = IDirect3DDevice9_BeginScene(device);
11800     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11801     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
11802     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11803     hr = IDirect3DDevice9_EndScene(device);
11804     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11805
11806     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11807     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11808
11809     hr = IDirect3DDevice9_BeginScene(device);
11810     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11811     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
11812     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11813     hr = IDirect3DDevice9_EndScene(device);
11814     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11815
11816     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11817     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11818     IDirect3DSurface9_Release(ds);
11819     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11820     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11821     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11822     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11823
11824     /* Read the depth values back. */
11825     hr = IDirect3DDevice9_BeginScene(device);
11826     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11827     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11828     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11829     hr = IDirect3DDevice9_EndScene(device);
11830     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11831
11832     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11833     {
11834         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11835         ok(color_match(color, expected_colors[i].color, 1),
11836                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11837                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11838     }
11839
11840     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11841     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11842
11843     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11844     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11845     IDirect3DSurface9_Release(original_ds);
11846     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11847     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11848     IDirect3DTexture9_Release(texture);
11849     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11850     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11851     IDirect3DPixelShader9_Release(ps);
11852
11853     IDirect3DSurface9_Release(original_rt);
11854     IDirect3DSurface9_Release(rt);
11855 }
11856
11857 static void shadow_test(IDirect3DDevice9 *device)
11858 {
11859     static const DWORD ps_code[] =
11860     {
11861         0xffff0200,                                                             /* ps_2_0                       */
11862         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11863         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11864         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11865         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11866         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11867         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11868         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11869         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11870         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11871         0x0000ffff,                                                             /* end                          */
11872     };
11873     struct
11874     {
11875         D3DFORMAT format;
11876         const char *name;
11877     }
11878     formats[] =
11879     {
11880         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
11881         {D3DFMT_D32,            "D3DFMT_D32"},
11882         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
11883         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
11884         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
11885         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
11886         {D3DFMT_D16,            "D3DFMT_D16"},
11887         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
11888         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
11889     };
11890     struct
11891     {
11892         float x, y, z;
11893         float s, t, p, q;
11894     }
11895     quad[] =
11896     {
11897         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11898         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11899         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11900         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11901     };
11902     struct
11903     {
11904         UINT x, y;
11905         D3DCOLOR color;
11906     }
11907     expected_colors[] =
11908     {
11909         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11910         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11911         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11912         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11913         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11914         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11915         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11916         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11917     };
11918
11919     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11920     IDirect3DPixelShader9 *ps;
11921     IDirect3D9 *d3d9;
11922     D3DCAPS9 caps;
11923     HRESULT hr;
11924     UINT i;
11925
11926     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11927     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11928     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11929     {
11930         skip("No pixel shader 2.0 support, skipping shadow test.\n");
11931         return;
11932     }
11933
11934     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11935     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11936     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11937     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11938     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11939     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11940
11941     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11942             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11943     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11944     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11945     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11946
11947     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11948     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11949     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11950     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11951     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11952     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11953     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11954     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11955     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11956     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11957
11958     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11959     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11960     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11961     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11962     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11963     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11964     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11965     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11966     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11967     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11968
11969     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11970     {
11971         D3DFORMAT format = formats[i].format;
11972         IDirect3DTexture9 *texture;
11973         IDirect3DSurface9 *ds;
11974         unsigned int j;
11975
11976         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11977                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11978         if (FAILED(hr)) continue;
11979
11980         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11981                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11982         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11983
11984         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11985         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11986
11987         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11988         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11989
11990         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11991         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11992
11993         IDirect3DDevice9_SetPixelShader(device, NULL);
11994         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11995
11996         /* Setup the depth/stencil surface. */
11997         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11998         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11999
12000         hr = IDirect3DDevice9_BeginScene(device);
12001         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12002         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12003         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12004         hr = IDirect3DDevice9_EndScene(device);
12005         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12006
12007         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
12008         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12009         IDirect3DSurface9_Release(ds);
12010
12011         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12012         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12013
12014         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12015         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12016
12017         hr = IDirect3DDevice9_SetPixelShader(device, ps);
12018         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12019
12020         /* Do the actual shadow mapping. */
12021         hr = IDirect3DDevice9_BeginScene(device);
12022         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12023         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12024         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12025         hr = IDirect3DDevice9_EndScene(device);
12026         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12027
12028         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12029         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12030         IDirect3DTexture9_Release(texture);
12031
12032         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
12033         {
12034             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
12035             ok(color_match(color, expected_colors[j].color, 0),
12036                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
12037                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
12038                     formats[i].name, color);
12039         }
12040
12041         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12042         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12043     }
12044
12045     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12046     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12047     IDirect3DPixelShader9_Release(ps);
12048
12049     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
12050     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12051     IDirect3DSurface9_Release(original_ds);
12052
12053     IDirect3DSurface9_Release(original_rt);
12054     IDirect3DSurface9_Release(rt);
12055
12056     IDirect3D9_Release(d3d9);
12057 }
12058
12059 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
12060 {
12061     const struct vertex quad1[] =
12062     {
12063         {-1.0f, -1.0f, 0.0f, 0xfff9e814},
12064         { 1.0f, -1.0f, 0.0f, 0xfff9e814},
12065         {-1.0f,  1.0f, 0.0f, 0xfff9e814},
12066         { 1.0f,  1.0f, 0.0f, 0xfff9e814},
12067     };
12068     const struct vertex quad2[] =
12069     {
12070         {-1.0f, -1.0f, 0.0f, 0xff002b7f},
12071         { 1.0f, -1.0f, 0.0f, 0xff002b7f},
12072         {-1.0f,  1.0f, 0.0f, 0xff002b7f},
12073         { 1.0f,  1.0f, 0.0f, 0xff002b7f},
12074     };
12075     D3DCOLOR color;
12076     HRESULT hr;
12077
12078     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
12079     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12080
12081     hr = IDirect3DDevice9_BeginScene(device);
12082     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12083
12084     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12085     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12086
12087     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12088     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12089     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12090     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12091
12092     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
12093     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12094     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12095     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12096
12097     hr = IDirect3DDevice9_EndScene(device);
12098     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12099
12100     color = getPixelColor(device, 1, 240);
12101     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12102     color = getPixelColor(device, 638, 240);
12103     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12104
12105     color = getPixelColor(device, 1, 241);
12106     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12107     color = getPixelColor(device, 638, 241);
12108     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12109 }
12110
12111 static void clip_planes_test(IDirect3DDevice9 *device)
12112 {
12113     const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
12114
12115     const DWORD shader_code[] = {
12116         0xfffe0200, /* vs_2_0 */
12117         0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12118         0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
12119         0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12120         0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
12121         0x0000ffff /* end */
12122     };
12123     IDirect3DVertexShader9 *shader;
12124
12125     IDirect3DTexture9 *offscreen = NULL;
12126     IDirect3DSurface9 *offscreen_surface, *original_rt;
12127     HRESULT hr;
12128
12129     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12130     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12131
12132     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12133     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12134     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12135     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12136     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12137     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12138     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
12139     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12140
12141     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12142     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12143     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12144     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
12145
12146     IDirect3DDevice9_SetClipPlane(device, 0, plane0);
12147
12148     clip_planes(device, "Onscreen FFP");
12149
12150     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
12151     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12152     hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
12153     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12154     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12155     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12156
12157     clip_planes(device, "Offscreen FFP");
12158
12159     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12160     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12161
12162     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12163     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
12164     IDirect3DDevice9_SetVertexShader(device, shader);
12165     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
12166
12167     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12168     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12169
12170     clip_planes(device, "Onscreen vertex shader");
12171
12172     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12173     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12174
12175     clip_planes(device, "Offscreen vertex shader");
12176
12177     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12178     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12179
12180     IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12181     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12182     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12183     IDirect3DVertexShader9_Release(shader);
12184     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12185     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12186     IDirect3DSurface9_Release(original_rt);
12187     IDirect3DSurface9_Release(offscreen_surface);
12188     IDirect3DTexture9_Release(offscreen);
12189 }
12190
12191 static void fp_special_test(IDirect3DDevice9 *device)
12192 {
12193     static const DWORD vs_header[] =
12194     {
12195         0xfffe0200,                                                             /* vs_2_0                       */
12196         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
12197         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
12198         0x0200001f, 0x80000005, 0x900f0001,                                     /* dcl_texcoord0 v1             */
12199     };
12200
12201     static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001};         /* log r0.x, v1.x               */
12202     static const DWORD vs_pow[] =
12203             {0x03000020, 0x80010000, 0x90000001, 0x90000001};                   /* pow r0.x, v1.x, v1.x         */
12204     static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001};         /* nrm r0.xyz, v1.x             */
12205     static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001};        /* rcp r0.x, v1.x               */
12206     static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001};        /* rcp r0.x, -v1.x              */
12207     static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001};        /* rsq r0.x, v1.x               */
12208     static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001};        /* rsq r0.x, -v1.x              */
12209     static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001,          /* lit r0, v1.xxxx              */
12210             0x02000001, 0x80010000, 0x80aa0000};                                /* mov r0.x, v0.z               */
12211
12212     static const DWORD vs_footer[] =
12213     {
12214         0x03000005, 0x80020000, 0x80000000, 0xa0ff0000,                         /* mul r0.y, r0.x, c0.w         */
12215         0x0300000d, 0x80040000, 0x80000000, 0x80550000,                         /* sge r0.z, r0.x, r0.y         */
12216         0x0300000d, 0x80020000, 0x80e40000, 0x80000000,                         /* sge r0.y, r0, r0.x           */
12217         0x03000005, 0x80040000, 0x80550000, 0x80e40000,                         /* mul r0.z, r0.y, r0           */
12218         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
12219         0x0300000c, 0x80020000, 0x80000000, 0x80000000,                         /* slt r0.y, r0.x, r0.x         */
12220         0x03000002, 0x80040000, 0x80550000, 0x80550000,                         /* add r0.z, r0.y, r0.y         */
12221         0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000,                         /* slt r0.y, c0.x, r0.w         */
12222         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
12223         0x03000002, 0x80040000, 0x81550000, 0xa0e40000,                         /* add r0.z, -r0.y, c0          */
12224         0x0300000c, 0x80080000, 0xa0000000, 0x80e40000,                         /* slt r0.w, c0.x, r0           */
12225         0x03000005, 0x80040000, 0x80ff0000, 0x80e40000,                         /* mul r0.z, r0.w, r0           */
12226         0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000,             /* mad r0.y, r0.z, c0, r0       */
12227         0x02000001, 0xe0030000, 0x80e40000,                                     /* mov oT0.xy, r0               */
12228         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
12229         0x0000ffff,                                                             /* end                          */
12230     };
12231
12232     static const struct
12233     {
12234         const char *name;
12235         const DWORD *ops;
12236         DWORD size;
12237         D3DCOLOR r600;
12238         D3DCOLOR nv40;
12239         D3DCOLOR nv50;
12240     }
12241     vs_body[] =
12242     {
12243         /* The basic ideas here are:
12244          *     2.0 * +/-INF == +/-INF
12245          *     NAN != NAN
12246          *
12247          * The vertex shader value is written to the red component, with 0.0
12248          * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
12249          * result in 0x00. The pixel shader value is written to the green
12250          * component, but here 0.0 also results in 0x00. The actual value is
12251          * written to the blue component.
12252          *
12253          * There are considerable differences between graphics cards in how
12254          * these are handled, but pow and nrm never generate INF or NAN. */
12255         {"log",     vs_log,     sizeof(vs_log),     0x00000000, 0x00ff0000, 0x00ff7f00},
12256         {"pow",     vs_pow,     sizeof(vs_pow),     0x000000ff, 0x0000ff00, 0x000000ff},
12257         {"nrm",     vs_nrm,     sizeof(vs_nrm),     0x00ff0000, 0x0000ff00, 0x00ff0000},
12258         {"rcp1",    vs_rcp1,    sizeof(vs_rcp1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12259         {"rcp2",    vs_rcp2,    sizeof(vs_rcp2),    0x00000000, 0x00ff0000, 0x00ff7f00},
12260         {"rsq1",    vs_rsq1,    sizeof(vs_rsq1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12261         {"rsq2",    vs_rsq2,    sizeof(vs_rsq2),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12262         {"lit",     vs_lit,     sizeof(vs_lit),     0x00ff0000, 0x00ff0000, 0x00ff0000},
12263     };
12264
12265     static const DWORD ps_code[] =
12266     {
12267         0xffff0200,                                                             /* ps_2_0                       */
12268         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
12269         0x0200001f, 0x80000000, 0xb0030000,                                     /* dcl t0.xy                    */
12270         0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000,                         /* max r1.x, t0, c0             */
12271         0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000,                         /* min r0.x, t0, c0             */
12272         0x03000002, 0x80010000, 0x80e40000, 0x81e40001,                         /* add r0.x, r0, -r1            */
12273         0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000,             /* mad r1.x, t0, c0.w. -t0      */
12274         0x02000023, 0x80010002, 0x80e40001,                                     /* abs r2.x, r1                 */
12275         0x02000023, 0x80010000, 0x80e40000,                                     /* abs r0.x, r0                 */
12276         0x02000023, 0x80010001, 0xb0e40000,                                     /* abs r1.x, t0                 */
12277         0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r2, c0.z, c0      */
12278         0x02000023, 0x80010002, 0x80e40002,                                     /* abs r2.x, r2                 */
12279         0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r1.x, -r1, c0.z, c0      */
12280         0x02000023, 0x80010001, 0x80e40001,                                     /* abs r1.x, r1                 */
12281         0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r3.x, -r2, c0.z, c0      */
12282         0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r1, c0.z, c0      */
12283         0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000,             /* cmp r0.x, -r0, c0.y, c0      */
12284         0x03000005, 0x80010002, 0x80e40002, 0x80e40003,                         /* mul r2.x, r2, r3             */
12285         0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000,             /* cmp r0.x, -r2, c0.z, r0      */
12286         0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000,             /* cmp r0.y, -r1.x, r0.x, c0.x  */
12287         0x02000001, 0x80050000, 0xb0c90000,                                     /* mov r0.xz, t0.yzxw           */
12288         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.w, c0.z               */
12289         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
12290         0x0000ffff,                                                             /* end                          */
12291     };
12292
12293     struct
12294     {
12295         float x, y, z;
12296         float s;
12297     }
12298     quad[] =
12299     {
12300         { -1.0f,  1.0f, 0.0f, 0.0f},
12301         {  1.0f,  1.0f, 1.0f, 0.0f},
12302         { -1.0f, -1.0f, 0.0f, 0.0f},
12303         {  1.0f, -1.0f, 1.0f, 0.0f},
12304     };
12305
12306     IDirect3DPixelShader9 *ps;
12307     UINT body_size = 0;
12308     DWORD *vs_code;
12309     D3DCAPS9 caps;
12310     HRESULT hr;
12311     UINT i;
12312
12313     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12314     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12315     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12316     {
12317         skip("No shader model 2.0 support, skipping floating point specials test.\n");
12318         return;
12319     }
12320
12321     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
12322     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12323
12324     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12325     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12326     IDirect3DDevice9_SetPixelShader(device, ps);
12327     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12328
12329     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12330     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12331
12332     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
12333     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12334
12335     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12336     {
12337         if (vs_body[i].size > body_size) body_size = vs_body[i].size;
12338     }
12339
12340     vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
12341     memcpy(vs_code, vs_header, sizeof(vs_header));
12342
12343     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12344     {
12345         DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
12346         IDirect3DVertexShader9 *vs;
12347         D3DCOLOR color;
12348
12349         memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
12350         offset += vs_body[i].size / sizeof(*vs_body[i].ops);
12351         memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
12352
12353         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
12354         ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
12355         IDirect3DDevice9_SetVertexShader(device, vs);
12356         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12357
12358         hr = IDirect3DDevice9_BeginScene(device);
12359         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12360         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12361         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12362         hr = IDirect3DDevice9_EndScene(device);
12363         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12364
12365         color = getPixelColor(device, 320, 240);
12366         ok(color_match(color, vs_body[i].r600, 1)
12367                 || color_match(color, vs_body[i].nv40, 1)
12368                 || color_match(color, vs_body[i].nv50, 1),
12369                 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
12370                 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
12371
12372         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12373         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12374
12375         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12376         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12377         IDirect3DVertexShader9_Release(vs);
12378     }
12379
12380     HeapFree(GetProcessHeap(), 0, vs_code);
12381
12382     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12383     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12384     IDirect3DPixelShader9_Release(ps);
12385 }
12386
12387 static void srgbwrite_format_test(IDirect3DDevice9 *device)
12388 {
12389     IDirect3D9 *d3d;
12390     IDirect3DSurface9 *rt, *backbuffer;
12391     IDirect3DTexture9 *texture;
12392     HRESULT hr;
12393     int i;
12394     DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
12395     static const struct
12396     {
12397         D3DFORMAT fmt;
12398         const char *name;
12399     }
12400     formats[] =
12401     {
12402         { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
12403         { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
12404         { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
12405         { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
12406         { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
12407     };
12408     static const struct
12409     {
12410         float x, y, z;
12411         float u, v;
12412     }
12413     quad[] =
12414     {
12415         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12416         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12417         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12418         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12419     };
12420
12421     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12422     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12423     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12424     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12425     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
12426     ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
12427     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12428     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12429     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12430     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12431
12432     for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
12433     {
12434         if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12435                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
12436         {
12437             skip("Format %s not supported as render target, skipping test.\n",
12438                     formats[i].name);
12439             continue;
12440         }
12441
12442         hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
12443                                             D3DPOOL_DEFAULT, &texture, NULL);
12444         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12445         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
12446         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12447
12448         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
12449         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12450         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12451         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12452         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
12453         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12454
12455         hr = IDirect3DDevice9_BeginScene(device);
12456         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12457         if(SUCCEEDED(hr))
12458         {
12459             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
12460             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12461             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
12462             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12463             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12464             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12465
12466             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
12467             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12468             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12469             ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12470             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
12471             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12472             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12473             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12474             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12475             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12476             hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12477             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12478
12479             hr = IDirect3DDevice9_EndScene(device);
12480             ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12481         }
12482
12483         IDirect3DSurface9_Release(rt);
12484         IDirect3DTexture9_Release(texture);
12485
12486         color = getPixelColor(device, 360, 240);
12487         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12488                                     D3DUSAGE_QUERY_SRGBWRITE,
12489                                     D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
12490         {
12491             /* Big slop for R5G6B5 */
12492             ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
12493                 formats[i].name, color_srgb, color);
12494         }
12495         else
12496         {
12497             /* Big slop for R5G6B5 */
12498             ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
12499                 formats[i].name, color_rgb, color);
12500         }
12501
12502         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12503         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12504     }
12505
12506     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12507     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12508
12509     IDirect3D9_Release(d3d);
12510     IDirect3DSurface9_Release(backbuffer);
12511 }
12512
12513 static void ds_size_test(IDirect3DDevice9 *device)
12514 {
12515     IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
12516     HRESULT hr;
12517     DWORD num_passes;
12518     struct
12519     {
12520         float x, y, z;
12521     }
12522     quad[] =
12523     {
12524         {-1.0,  -1.0,   0.0 },
12525         {-1.0,   1.0,   0.0 },
12526         { 1.0,  -1.0,   0.0 },
12527         { 1.0,   1.0,   0.0 }
12528     };
12529
12530     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12531     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12532     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
12533     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
12534     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
12535     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
12536
12537     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12538     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12539     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
12540     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12541     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12542     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12543     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12544     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12545     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12546     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12547     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
12548     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
12549     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12550     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12551     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12552     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12553     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12554     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12555
12556     /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
12557      * but does not change the surface's contents. */
12558     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
12559     ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
12560     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
12561     ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
12562     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
12563     ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12564
12565     /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
12566
12567     /* Turning on any depth-related state results in a ValidateDevice failure */
12568     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12569     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12570     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12571     ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12572         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12573     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12574     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12575     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12576     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12577     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12578     ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12579         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12580
12581     /* Try to draw with the device in an invalid state */
12582     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12583     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12584     hr = IDirect3DDevice9_BeginScene(device);
12585     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12586     if(SUCCEEDED(hr))
12587     {
12588         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12589         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12590         hr = IDirect3DDevice9_EndScene(device);
12591         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12592
12593         /* Don't check the resulting draw unless we find an app that needs it. On nvidia ValidateDevice
12594          * returns CONFLICTINGRENDERSTATE, so the result is undefined. On AMD d3d seems to assume the
12595          * stored Z buffer value is 0.0 for all pixels, even those that are covered by the depth buffer */
12596     }
12597
12598     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12599     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12600     hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12601     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12602     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12603     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12604
12605     IDirect3DSurface9_Release(readback);
12606     IDirect3DSurface9_Release(ds);
12607     IDirect3DSurface9_Release(rt);
12608     IDirect3DSurface9_Release(old_rt);
12609     IDirect3DSurface9_Release(old_ds);
12610 }
12611
12612 static void unbound_sampler_test(IDirect3DDevice9 *device)
12613 {
12614     HRESULT hr;
12615     IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
12616     IDirect3DSurface9 *rt, *old_rt;
12617     DWORD color;
12618
12619     static const DWORD ps_code[] =
12620     {
12621         0xffff0200,                                     /* ps_2_0           */
12622         0x0200001f, 0x90000000, 0xa00f0800,             /* dcl_2d s0        */
12623         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12624         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12625         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12626         0x0000ffff,                                     /* end              */
12627     };
12628     static const DWORD ps_code_cube[] =
12629     {
12630         0xffff0200,                                     /* ps_2_0           */
12631         0x0200001f, 0x98000000, 0xa00f0800,             /* dcl_cube s0      */
12632         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12633         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12634         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12635         0x0000ffff,                                     /* end              */
12636     };
12637     static const DWORD ps_code_volume[] =
12638     {
12639         0xffff0200,                                     /* ps_2_0           */
12640         0x0200001f, 0xa0000000, 0xa00f0800,             /* dcl_volume s0    */
12641         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12642         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12643         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12644         0x0000ffff,                                     /* end              */
12645     };
12646
12647     static const struct
12648     {
12649         float x, y, z;
12650         float u, v;
12651     }
12652     quad[] =
12653     {
12654         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12655         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12656         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12657         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12658     };
12659
12660     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12661     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
12662
12663     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12664     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12665     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
12666     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12667     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
12668     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12669
12670     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
12671     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12672
12673     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12674     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12675
12676     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12677     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12678
12679     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
12680     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12681
12682     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
12683     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
12684
12685     hr = IDirect3DDevice9_SetPixelShader(device, ps);
12686     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12687
12688     hr = IDirect3DDevice9_BeginScene(device);
12689     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12690     if(SUCCEEDED(hr))
12691     {
12692         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12693         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12694
12695         hr = IDirect3DDevice9_EndScene(device);
12696         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12697     }
12698
12699     color = getPixelColorFromSurface(rt, 32, 32);
12700     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12701
12702     /* Now try with a cube texture */
12703     hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
12704     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12705
12706     hr = IDirect3DDevice9_BeginScene(device);
12707     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12708     if (SUCCEEDED(hr))
12709     {
12710         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12711         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12712
12713         hr = IDirect3DDevice9_EndScene(device);
12714         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12715     }
12716
12717     color = getPixelColorFromSurface(rt, 32, 32);
12718     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12719
12720     /* And then with a volume texture */
12721     hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
12722     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12723
12724     hr = IDirect3DDevice9_BeginScene(device);
12725     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12726     if (SUCCEEDED(hr))
12727     {
12728         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12729         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12730
12731         hr = IDirect3DDevice9_EndScene(device);
12732         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12733     }
12734
12735     color = getPixelColorFromSurface(rt, 32, 32);
12736     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12737
12738     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12739     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12740
12741     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12742     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12743
12744     IDirect3DSurface9_Release(rt);
12745     IDirect3DSurface9_Release(old_rt);
12746     IDirect3DPixelShader9_Release(ps);
12747     IDirect3DPixelShader9_Release(ps_cube);
12748     IDirect3DPixelShader9_Release(ps_volume);
12749 }
12750
12751 static void update_surface_test(IDirect3DDevice9 *device)
12752 {
12753     static const BYTE blocks[][8] =
12754     {
12755         {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
12756         {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
12757         {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
12758         {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
12759         {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
12760         {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
12761         {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
12762     };
12763     static const struct
12764     {
12765         UINT x, y;
12766         D3DCOLOR color;
12767     }
12768     expected_colors[] =
12769     {
12770         { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
12771         { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
12772         {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
12773         {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12774         {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12775         {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12776         {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
12777     };
12778     static const struct
12779     {
12780         float x, y, z, w;
12781         float u, v;
12782     }
12783     tri[] =
12784     {
12785         {  0.0f, 480.0f, 0.0f,  1.0f,   0.0f, 0.0f},
12786         {  0.0f,   0.0f, 0.0f,  1.0f,   0.0f, 1.0f},
12787         {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
12788     };
12789     static const RECT rect_2x2 = {0, 0, 2, 2};
12790     static const struct
12791     {
12792         UINT src_level;
12793         UINT dst_level;
12794         const RECT *r;
12795         HRESULT hr;
12796     }
12797     block_size_tests[] =
12798     {
12799         {1, 0, NULL,      D3D_OK},
12800         {0, 1, NULL,      D3DERR_INVALIDCALL},
12801         {5, 4, NULL,      D3DERR_INVALIDCALL},
12802         {4, 5, NULL,      D3DERR_INVALIDCALL},
12803         {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
12804         {5, 5, &rect_2x2, D3D_OK},
12805     };
12806
12807     IDirect3DSurface9 *src_surface, *dst_surface;
12808     IDirect3DTexture9 *src_tex, *dst_tex;
12809     IDirect3D9 *d3d;
12810     UINT count, i;
12811     HRESULT hr;
12812
12813     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12814     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12815
12816     hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12817             D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
12818     IDirect3D9_Release(d3d);
12819     if (FAILED(hr))
12820     {
12821         skip("DXT1 not supported, skipping test.\n");
12822         return;
12823     }
12824
12825     IDirect3D9_Release(d3d);
12826
12827     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
12828     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12829     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
12830     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12831
12832     count = IDirect3DTexture9_GetLevelCount(src_tex);
12833     ok(count == 7, "Got level count %u, expected 7.\n", count);
12834
12835     for (i = 0; i < count; ++i)
12836     {
12837         UINT row_count, block_count, x, y;
12838         D3DSURFACE_DESC desc;
12839         BYTE *row, *block;
12840         D3DLOCKED_RECT r;
12841
12842         hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
12843         ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
12844
12845         hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
12846         ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
12847
12848         row_count = ((desc.Height + 3) & ~3) / 4;
12849         block_count = ((desc.Width + 3) & ~3) / 4;
12850         row = r.pBits;
12851
12852         for (y = 0; y < row_count; ++y)
12853         {
12854             block = row;
12855             for (x = 0; x < block_count; ++x)
12856             {
12857                 memcpy(block, blocks[i], sizeof(blocks[i]));
12858                 block += sizeof(blocks[i]);
12859             }
12860             row += r.Pitch;
12861         }
12862
12863         hr = IDirect3DTexture9_UnlockRect(src_tex, i);
12864         ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
12865     }
12866
12867     for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
12868     {
12869         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
12870         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12871         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
12872         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12873
12874         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
12875         ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
12876                 hr, i, block_size_tests[i].hr);
12877
12878         IDirect3DSurface9_Release(dst_surface);
12879         IDirect3DSurface9_Release(src_surface);
12880     }
12881
12882     for (i = 0; i < count; ++i)
12883     {
12884         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
12885         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12886         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
12887         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12888
12889         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
12890         ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
12891
12892         IDirect3DSurface9_Release(dst_surface);
12893         IDirect3DSurface9_Release(src_surface);
12894     }
12895
12896     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12897     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12898     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12899     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12900     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
12901     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12902     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
12903     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12904     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12905     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12906     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12907     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12908
12909     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
12910     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12911
12912     hr = IDirect3DDevice9_BeginScene(device);
12913     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12914     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
12915     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12916     hr = IDirect3DDevice9_EndScene(device);
12917     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12918
12919     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
12920     {
12921         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
12922         ok(color_match(color, expected_colors[i].color, 0),
12923                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
12924                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
12925     }
12926
12927     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12928     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12929
12930     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12931     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12932     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12933     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12934     IDirect3DTexture9_Release(dst_tex);
12935     IDirect3DTexture9_Release(src_tex);
12936 }
12937
12938 static void multisample_get_rtdata_test(IDirect3DDevice9 *device)
12939 {
12940     IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
12941     IDirect3D9 *d3d9;
12942     HRESULT hr;
12943
12944     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
12945     ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
12946     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
12947             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
12948     IDirect3D9_Release(d3d9);
12949     if (FAILED(hr))
12950     {
12951         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
12952         return;
12953     }
12954
12955     hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
12956             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
12957     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
12958     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
12959             D3DPOOL_SYSTEMMEM, &readback, NULL);
12960     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
12961
12962     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12963     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
12964     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
12965     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
12966
12967     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12968     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
12969     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
12970     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
12971
12972     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
12973     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
12974     hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
12975     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
12976
12977     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
12978     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
12979     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12980     ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
12981
12982     IDirect3DSurface9_Release(original_ds);
12983     IDirect3DSurface9_Release(original_rt);
12984     IDirect3DSurface9_Release(readback);
12985     IDirect3DSurface9_Release(rt);
12986 }
12987
12988 static void multisampled_depth_buffer_test(IDirect3D9 *d3d9)
12989 {
12990     IDirect3DDevice9 *device = 0;
12991     IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
12992     D3DCAPS9 caps;
12993     HRESULT hr;
12994     D3DPRESENT_PARAMETERS present_parameters;
12995     unsigned int i;
12996     static const struct
12997     {
12998         float x, y, z;
12999         D3DCOLOR color;
13000     }
13001     quad_1[] =
13002     {
13003         { -1.0f,  1.0f, 0.0f, 0xffff0000},
13004         {  1.0f,  1.0f, 1.0f, 0xffff0000},
13005         { -1.0f, -1.0f, 0.0f, 0xffff0000},
13006         {  1.0f, -1.0f, 1.0f, 0xffff0000},
13007     },
13008     quad_2[] =
13009     {
13010         { -1.0f,  1.0f, 1.0f, 0xff0000ff},
13011         {  1.0f,  1.0f, 0.0f, 0xff0000ff},
13012         { -1.0f, -1.0f, 1.0f, 0xff0000ff},
13013         {  1.0f, -1.0f, 0.0f, 0xff0000ff},
13014     };
13015     static const struct
13016     {
13017         UINT x, y;
13018         D3DCOLOR color;
13019     }
13020     expected_colors[] =
13021     {
13022         { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13023         {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13024         {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13025         {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13026         { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13027         {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13028         {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13029         {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13030     };
13031
13032     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13033             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13034     if (FAILED(hr))
13035     {
13036         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
13037         return;
13038     }
13039     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13040             D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13041     if (FAILED(hr))
13042     {
13043         skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
13044         return;
13045     }
13046
13047     ZeroMemory(&present_parameters, sizeof(present_parameters));
13048     present_parameters.Windowed = TRUE;
13049     present_parameters.hDeviceWindow = create_window();
13050     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13051     present_parameters.BackBufferWidth = 640;
13052     present_parameters.BackBufferHeight = 480;
13053     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13054     present_parameters.EnableAutoDepthStencil = TRUE;
13055     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13056     present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13057
13058     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13059             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13060             &present_parameters, &device);
13061     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13062
13063     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13064     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13065     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13066     {
13067         skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
13068         goto cleanup;
13069     }
13070
13071     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13072             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13073     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13074     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13075             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13076     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13077
13078     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13079     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13080     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13081     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13082
13083     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13084     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13085     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13086     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13087     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13088     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13089     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13090     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13091     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13092     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13093
13094     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13095     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13096
13097     /* Render onscreen and then offscreen */
13098     hr = IDirect3DDevice9_BeginScene(device);
13099     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13100     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13101     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13102     hr = IDirect3DDevice9_EndScene(device);
13103     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13104
13105     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
13106     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13107     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13108     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13109
13110     hr = IDirect3DDevice9_BeginScene(device);
13111     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13112     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13113     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13114     hr = IDirect3DDevice9_EndScene(device);
13115     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13116
13117     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
13118     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13119
13120     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13121     {
13122         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13123         ok(color_match(color, expected_colors[i].color, 1),
13124                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13125                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13126     }
13127
13128     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13129     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13130     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13131     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13132
13133     /* Render offscreen and then onscreen */
13134     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13135     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13136     IDirect3DSurface9_Release(ds);
13137     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13138             D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13139     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13140     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13141
13142     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13143     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13144
13145     hr = IDirect3DDevice9_BeginScene(device);
13146     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13147     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13148     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13149     hr = IDirect3DDevice9_EndScene(device);
13150     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13151
13152     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13153     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13154     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13155     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13156
13157     hr = IDirect3DDevice9_BeginScene(device);
13158     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13159     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13160     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13161     hr = IDirect3DDevice9_EndScene(device);
13162     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13163
13164     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13165     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13166
13167     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13168     {
13169         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13170         ok(color_match(color, expected_colors[i].color, 1),
13171                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13172                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13173     }
13174
13175     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13176     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13177
13178     IDirect3DSurface9_Release(ds);
13179     IDirect3DSurface9_Release(readback);
13180     IDirect3DSurface9_Release(rt);
13181     IDirect3DSurface9_Release(original_rt);
13182     cleanup_device(device);
13183
13184     ZeroMemory(&present_parameters, sizeof(present_parameters));
13185     present_parameters.Windowed = TRUE;
13186     present_parameters.hDeviceWindow = create_window();
13187     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13188     present_parameters.BackBufferWidth = 640;
13189     present_parameters.BackBufferHeight = 480;
13190     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13191     present_parameters.EnableAutoDepthStencil = TRUE;
13192     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13193     present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13194
13195     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13196             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13197             &present_parameters, &device);
13198     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13199
13200     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
13201     ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
13202
13203     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13204             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13205     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13206     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13207             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13208     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13209     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13210             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
13211     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13212
13213     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13214     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13215     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13216     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13217     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13218     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13219     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13220     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13221
13222     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13223     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13224     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13225     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13226     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13227     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13228     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13229     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13230     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13231     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13232
13233     /* Render to a multisampled offscreen frame buffer and then blit to
13234      * the onscreen (not multisampled) frame buffer. */
13235     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13236     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13237
13238     hr = IDirect3DDevice9_BeginScene(device);
13239     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13240     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13241     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13242     hr = IDirect3DDevice9_EndScene(device);
13243     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13244
13245     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13246     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13247     hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
13248     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13249
13250     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13251     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13252     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13253     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13254
13255     hr = IDirect3DDevice9_BeginScene(device);
13256     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13257     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13258     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13259     hr = IDirect3DDevice9_EndScene(device);
13260     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13261
13262     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13263     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13264
13265     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13266     {
13267         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13268         if (i % 4 < 2)
13269             todo_wine ok(color_match(color, expected_colors[i].color, 1),
13270                     "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13271                     expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13272         else
13273             ok(color_match(color, expected_colors[i].color, 1),
13274                     "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13275                     expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13276     }
13277
13278     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13279     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13280
13281     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13282     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13283     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13284     ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13285
13286     IDirect3DSurface9_Release(original_ds);
13287     IDirect3DSurface9_Release(original_rt);
13288     IDirect3DSurface9_Release(ds);
13289     IDirect3DSurface9_Release(readback);
13290     IDirect3DSurface9_Release(rt);
13291 cleanup:
13292     cleanup_device(device);
13293 }
13294
13295 static void resz_test(IDirect3D9 *d3d9)
13296 {
13297     IDirect3DDevice9 *device = 0;
13298     IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
13299     D3DCAPS9 caps;
13300     HRESULT hr;
13301     D3DPRESENT_PARAMETERS present_parameters;
13302     unsigned int i;
13303     static const DWORD ps_code[] =
13304     {
13305         0xffff0200,                                                             /* ps_2_0                       */
13306         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
13307         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
13308         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
13309         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
13310         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
13311         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
13312         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
13313         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
13314         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
13315         0x0000ffff,                                                             /* end                          */
13316     };
13317     struct
13318     {
13319         float x, y, z;
13320         float s, t, p, q;
13321     }
13322     quad[] =
13323     {
13324         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13325         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13326         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13327         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13328     };
13329     struct
13330     {
13331         UINT x, y;
13332         D3DCOLOR color;
13333     }
13334     expected_colors[] =
13335     {
13336         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13337         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13338         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13339         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13340         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13341         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13342         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13343         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13344     };
13345     IDirect3DTexture9 *texture;
13346     IDirect3DPixelShader9 *ps;
13347     DWORD value;
13348
13349     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13350             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13351     if (FAILED(hr))
13352     {
13353         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
13354         return;
13355     }
13356     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13357             D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13358     if (FAILED(hr))
13359     {
13360         skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
13361         return;
13362     }
13363
13364     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13365             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
13366     if (FAILED(hr))
13367     {
13368         skip("No INTZ support, skipping RESZ test.\n");
13369         return;
13370     }
13371
13372     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13373             D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'));
13374     if (FAILED(hr))
13375     {
13376         skip("No RESZ support, skipping RESZ test.\n");
13377         return;
13378     }
13379
13380     ZeroMemory(&present_parameters, sizeof(present_parameters));
13381     present_parameters.Windowed = TRUE;
13382     present_parameters.hDeviceWindow = create_window();
13383     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13384     present_parameters.BackBufferWidth = 640;
13385     present_parameters.BackBufferHeight = 480;
13386     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13387     present_parameters.EnableAutoDepthStencil = FALSE;
13388     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13389     present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13390
13391     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13392             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13393     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13394
13395     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13396     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13397     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
13398     {
13399         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
13400         cleanup_device(device);
13401         return;
13402     }
13403     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13404     {
13405         skip("No unconditional NP2 texture support, skipping INTZ test.\n");
13406         cleanup_device(device);
13407         return;
13408     }
13409
13410     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13411     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13412
13413     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13414             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13415     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13416     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13417             D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13418     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13419             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13420     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13421
13422     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13423             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13424     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13425     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13426     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13427     hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13428     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13429     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13430     ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13431     IDirect3DSurface9_Release(intz_ds);
13432     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13433     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13434
13435     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13436     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13437     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13438     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13439     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13440     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13441     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13442     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13443     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13444     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13445
13446     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13447     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13448     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13449     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13450     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13451     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13452     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13453     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13454     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13455     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13456
13457     /* Render offscreen (multisampled), blit the depth buffer
13458      * into the INTZ texture and then check its contents */
13459     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13460     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13461     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13462     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13463     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13464     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13465
13466     hr = IDirect3DDevice9_BeginScene(device);
13467     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13468     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13469     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13470
13471     /* The destination depth texture has to be bound to sampler 0 */
13472     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13473     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13474
13475     /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
13476     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13477     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13478     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13479     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13480     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13481     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13482     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13483     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13484     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13485     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13486     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13487     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13488     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13489     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13490
13491     /* The actual multisampled depth buffer resolve happens here */
13492     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13493     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13494     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13495     ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13496
13497     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13498     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13499     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13500     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13501
13502     /* Read the depth values back */
13503     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13504     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13505     hr = IDirect3DDevice9_EndScene(device);
13506     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13507
13508     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13509     {
13510         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13511         ok(color_match(color, expected_colors[i].color, 1),
13512                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13513                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13514     }
13515
13516     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13517     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13518
13519     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13520     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13521     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13522     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13523     IDirect3DSurface9_Release(ds);
13524     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13525     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13526     IDirect3DTexture9_Release(texture);
13527     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13528     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13529     IDirect3DPixelShader9_Release(ps);
13530     IDirect3DSurface9_Release(readback);
13531     IDirect3DSurface9_Release(original_rt);
13532     IDirect3DSurface9_Release(rt);
13533     cleanup_device(device);
13534
13535
13536     ZeroMemory(&present_parameters, sizeof(present_parameters));
13537     present_parameters.Windowed = TRUE;
13538     present_parameters.hDeviceWindow = create_window();
13539     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13540     present_parameters.BackBufferWidth = 640;
13541     present_parameters.BackBufferHeight = 480;
13542     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13543     present_parameters.EnableAutoDepthStencil = TRUE;
13544     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13545     present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13546
13547     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13548             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13549     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13550
13551     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13552     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13553     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13554     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13555     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13556             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13557     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13558     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13559             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13560     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13561     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13562     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13563     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13564     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13565     hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13566     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13567     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13568     ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13569     IDirect3DSurface9_Release(intz_ds);
13570     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13571     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13572
13573     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13574     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13575     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13576     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13577     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13578     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13579     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13580     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13581     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13582     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13583
13584     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13585     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13586     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13587     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13588     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13589     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13590     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13591     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13592     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13593     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13594
13595     /* Render onscreen, blit the depth buffer into the INTZ texture
13596      * and then check its contents */
13597     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13598     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13599     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13600     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13601     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13602     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13603
13604     hr = IDirect3DDevice9_BeginScene(device);
13605     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13606     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13607     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13608     hr = IDirect3DDevice9_EndScene(device);
13609     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13610
13611     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13612     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13613
13614     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13615     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13616     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13617     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13618     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13619     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13620     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13621     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13622     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13623     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13624     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13625     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13626     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13627     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13628
13629     /* The actual multisampled depth buffer resolve happens here */
13630     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13631     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13632     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13633     ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13634
13635     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13636     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13637     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13638     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13639
13640     /* Read the depth values back */
13641     hr = IDirect3DDevice9_BeginScene(device);
13642     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13643     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13644     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13645     hr = IDirect3DDevice9_EndScene(device);
13646     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13647
13648     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13649     {
13650         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13651         ok(color_match(color, expected_colors[i].color, 1),
13652                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13653                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13654     }
13655
13656     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13657     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13658
13659
13660     /* Test edge cases - try with no texture at all */
13661     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13662     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13663     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13664     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13665
13666     hr = IDirect3DDevice9_BeginScene(device);
13667     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13668     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13669     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13670     hr = IDirect3DDevice9_EndScene(device);
13671     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13672
13673     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13674     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13675
13676     /* With a non-multisampled depth buffer */
13677     IDirect3DSurface9_Release(ds);
13678     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13679             D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
13680
13681     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13682     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13683     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13684     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13685     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13686     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13687
13688     hr = IDirect3DDevice9_BeginScene(device);
13689     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13690     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13691     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13692
13693     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13694     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13695
13696     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13697     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13698     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13699     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13700     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13701     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13702     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13703     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13704     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13705     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13706     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13707     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13708     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13709     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13710     hr = IDirect3DDevice9_EndScene(device);
13711     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13712
13713     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13714     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13715
13716     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13717     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13718
13719     /* Read the depth values back. */
13720     hr = IDirect3DDevice9_BeginScene(device);
13721     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13722     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13723     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13724     hr = IDirect3DDevice9_EndScene(device);
13725     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13726
13727     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13728     {
13729         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13730         ok(color_match(color, expected_colors[i].color, 1),
13731                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13732                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13733     }
13734
13735     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13736     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13737
13738     /* Without a current depth-stencil buffer set */
13739     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13740     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13741     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13742     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13743
13744     hr = IDirect3DDevice9_BeginScene(device);
13745     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13746     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13747     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13748     hr = IDirect3DDevice9_EndScene(device);
13749     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13750
13751     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13752     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13753
13754     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13755     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13756     IDirect3DSurface9_Release(ds);
13757     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13758     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13759     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13760     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13761     IDirect3DTexture9_Release(texture);
13762     IDirect3DPixelShader9_Release(ps);
13763     IDirect3DSurface9_Release(readback);
13764     IDirect3DSurface9_Release(original_rt);
13765     cleanup_device(device);
13766 }
13767
13768 static void zenable_test(IDirect3DDevice9 *device)
13769 {
13770     static const struct
13771     {
13772         struct vec4 position;
13773         D3DCOLOR diffuse;
13774     }
13775     tquad[] =
13776     {
13777         {{  0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
13778         {{  0.0f,   0.0f, -0.5f, 1.0f}, 0xff00ff00},
13779         {{640.0f, 480.0f,  1.5f, 1.0f}, 0xff00ff00},
13780         {{640.0f,   0.0f,  1.5f, 1.0f}, 0xff00ff00},
13781     };
13782     D3DCOLOR color;
13783     D3DCAPS9 caps;
13784     HRESULT hr;
13785     UINT x, y;
13786     UINT i, j;
13787
13788     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
13789     ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
13790     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13791     ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
13792
13793     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
13794     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13795     hr = IDirect3DDevice9_BeginScene(device);
13796     ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13797     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
13798     ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13799     hr = IDirect3DDevice9_EndScene(device);
13800     ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13801
13802     for (i = 0; i < 4; ++i)
13803     {
13804         for (j = 0; j < 4; ++j)
13805         {
13806             x = 80 * ((2 * j) + 1);
13807             y = 60 * ((2 * i) + 1);
13808             color = getPixelColor(device, x, y);
13809             ok(color_match(color, 0x0000ff00, 1),
13810                     "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
13811         }
13812     }
13813
13814     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13815     ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
13816
13817     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13818     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13819
13820     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
13821             && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
13822     {
13823         static const DWORD vs_code[] =
13824         {
13825             0xfffe0101,                                 /* vs_1_1           */
13826             0x0000001f, 0x80000000, 0x900f0000,         /* dcl_position v0  */
13827             0x00000001, 0xc00f0000, 0x90e40000,         /* mov oPos, v0     */
13828             0x00000001, 0xd00f0000, 0x90e40000,         /* mov oD0, v0      */
13829             0x0000ffff
13830         };
13831         static const DWORD ps_code[] =
13832         {
13833             0xffff0101,                                 /* ps_1_1           */
13834             0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
13835             0x0000ffff                                  /* end              */
13836         };
13837         static const struct vec3 quad[] =
13838         {
13839             {-1.0f, -1.0f, -0.5f},
13840             {-1.0f,  1.0f, -0.5f},
13841             { 1.0f, -1.0f,  1.5f},
13842             { 1.0f,  1.0f,  1.5f},
13843         };
13844         static const D3DCOLOR expected[] =
13845         {
13846             0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
13847             0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
13848             0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
13849             0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
13850         };
13851
13852         IDirect3DVertexShader9 *vs;
13853         IDirect3DPixelShader9 *ps;
13854
13855         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13856         ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
13857         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
13858         ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
13859         hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13860         ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
13861         hr = IDirect3DDevice9_SetVertexShader(device, vs);
13862         ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13863         hr = IDirect3DDevice9_SetPixelShader(device, ps);
13864         ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
13865
13866         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
13867         ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13868         hr = IDirect3DDevice9_BeginScene(device);
13869         ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13870         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13871         ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13872         hr = IDirect3DDevice9_EndScene(device);
13873         ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13874
13875         for (i = 0; i < 4; ++i)
13876         {
13877             for (j = 0; j < 4; ++j)
13878             {
13879                 x = 80 * ((2 * j) + 1);
13880                 y = 60 * ((2 * i) + 1);
13881                 color = getPixelColor(device, x, y);
13882                 ok(color_match(color, expected[i * 4 + j], 1),
13883                         "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
13884             }
13885         }
13886
13887         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13888         ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
13889
13890         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13891         ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
13892         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
13893         ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13894         IDirect3DPixelShader9_Release(ps);
13895         IDirect3DVertexShader9_Release(vs);
13896     }
13897 }
13898
13899 START_TEST(visual)
13900 {
13901     IDirect3D9 *d3d9;
13902     IDirect3DDevice9 *device_ptr;
13903     D3DCAPS9 caps;
13904     HRESULT hr;
13905     DWORD color;
13906
13907     d3d9_handle = LoadLibraryA("d3d9.dll");
13908     if (!d3d9_handle)
13909     {
13910         skip("Could not load d3d9.dll\n");
13911         return;
13912     }
13913
13914     device_ptr = init_d3d9();
13915     if (!device_ptr)
13916     {
13917         skip("Creating the device failed\n");
13918         return;
13919     }
13920
13921     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
13922
13923     /* Check for the reliability of the returned data */
13924     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
13925     if(FAILED(hr))
13926     {
13927         skip("Clear failed, can't assure correctness of the test results, skipping\n");
13928         goto cleanup;
13929     }
13930
13931     color = getPixelColor(device_ptr, 1, 1);
13932     if(color !=0x00ff0000)
13933     {
13934         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
13935         goto cleanup;
13936     }
13937     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
13938
13939     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
13940     if(FAILED(hr))
13941     {
13942         skip("Clear failed, can't assure correctness of the test results, skipping\n");
13943         goto cleanup;
13944     }
13945
13946     color = getPixelColor(device_ptr, 639, 479);
13947     if(color != 0x0000ddee)
13948     {
13949         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
13950         goto cleanup;
13951     }
13952     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
13953
13954     /* Now execute the real tests */
13955     depth_clamp_test(device_ptr);
13956     stretchrect_test(device_ptr);
13957     lighting_test(device_ptr);
13958     clear_test(device_ptr);
13959     color_fill_test(device_ptr);
13960     fog_test(device_ptr);
13961     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
13962     {
13963         test_cube_wrap(device_ptr);
13964     } else {
13965         skip("No cube texture support\n");
13966     }
13967     z_range_test(device_ptr);
13968     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
13969     {
13970         maxmip_test(device_ptr);
13971     }
13972     else
13973     {
13974         skip("No mipmap support\n");
13975     }
13976     offscreen_test(device_ptr);
13977     ds_size_test(device_ptr);
13978     alpha_test(device_ptr);
13979     shademode_test(device_ptr);
13980     srgbtexture_test(device_ptr);
13981     release_buffer_test(device_ptr);
13982     float_texture_test(device_ptr);
13983     g16r16_texture_test(device_ptr);
13984     pixelshader_blending_test(device_ptr);
13985     texture_transform_flags_test(device_ptr);
13986     autogen_mipmap_test(device_ptr);
13987     fixed_function_decl_test(device_ptr);
13988     conditional_np2_repeat_test(device_ptr);
13989     fixed_function_bumpmap_test(device_ptr);
13990     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
13991         stencil_cull_test(device_ptr);
13992     } else {
13993         skip("No two sided stencil support\n");
13994     }
13995     pointsize_test(device_ptr);
13996     tssargtemp_test(device_ptr);
13997     np2_stretch_rect_test(device_ptr);
13998     yuv_color_test(device_ptr);
13999     zwriteenable_test(device_ptr);
14000     alphatest_test(device_ptr);
14001     viewport_test(device_ptr);
14002
14003     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
14004     {
14005         test_constant_clamp_vs(device_ptr);
14006         test_compare_instructions(device_ptr);
14007     }
14008     else skip("No vs_1_1 support\n");
14009
14010     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
14011     {
14012         test_mova(device_ptr);
14013         loop_index_test(device_ptr);
14014         sincos_test(device_ptr);
14015         sgn_test(device_ptr);
14016         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14017             test_vshader_input(device_ptr);
14018             test_vshader_float16(device_ptr);
14019             stream_test(device_ptr);
14020         } else {
14021             skip("No vs_3_0 support\n");
14022         }
14023     }
14024     else skip("No vs_2_0 support\n");
14025
14026     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
14027     {
14028         fog_with_shader_test(device_ptr);
14029     }
14030     else skip("No vs_1_1 and ps_1_1 support\n");
14031
14032     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
14033     {
14034         texbem_test(device_ptr);
14035         texdepth_test(device_ptr);
14036         texkill_test(device_ptr);
14037         x8l8v8u8_test(device_ptr);
14038         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
14039             constant_clamp_ps_test(device_ptr);
14040             cnd_test(device_ptr);
14041             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
14042                 dp2add_ps_test(device_ptr);
14043                 unbound_sampler_test(device_ptr);
14044                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14045                     nested_loop_test(device_ptr);
14046                     pretransformed_varying_test(device_ptr);
14047                     vFace_register_test(device_ptr);
14048                     vpos_register_test(device_ptr);
14049                     multiple_rendertargets_test(device_ptr);
14050                 } else {
14051                     skip("No ps_3_0 or vs_3_0 support\n");
14052                 }
14053             } else {
14054                 skip("No ps_2_0 support\n");
14055             }
14056         }
14057     }
14058     else skip("No ps_1_1 support\n");
14059
14060     texop_test(device_ptr);
14061     texop_range_test(device_ptr);
14062     alphareplicate_test(device_ptr);
14063     dp3_alpha_test(device_ptr);
14064     depth_buffer_test(device_ptr);
14065     depth_buffer2_test(device_ptr);
14066     depth_blit_test(device_ptr);
14067     intz_test(device_ptr);
14068     shadow_test(device_ptr);
14069     fp_special_test(device_ptr);
14070     depth_bounds_test(device_ptr);
14071     srgbwrite_format_test(device_ptr);
14072     clip_planes_test(device_ptr);
14073     update_surface_test(device_ptr);
14074     multisample_get_rtdata_test(device_ptr);
14075     zenable_test(device_ptr);
14076
14077     hr = IDirect3DDevice9_GetDirect3D(device_ptr, &d3d9);
14078     ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
14079     cleanup_device(device_ptr);
14080     device_ptr = NULL;
14081
14082     multisampled_depth_buffer_test(d3d9);
14083     resz_test(d3d9);
14084
14085     IDirect3D9_Release(d3d9);
14086
14087 cleanup:
14088     cleanup_device(device_ptr);
14089 }