d3d9/tests: Also test that render states get reset in test_reset().
[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         hr = 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     hr = 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     {
1693         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1694         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1695         IDirect3DSurface9_Release(backbuffer);
1696     }
1697     if(offscreenTexture) {
1698         IDirect3DTexture9_Release(offscreenTexture);
1699     }
1700     if(offscreen) {
1701         IDirect3DSurface9_Release(offscreen);
1702     }
1703 }
1704
1705 /* This test tests fog in combination with shaders.
1706  * What's tested: linear fog (vertex and table) with pixel shader
1707  *                linear table fog with non foggy vertex shader
1708  *                vertex fog with foggy vertex shader, non-linear
1709  *                fog with shader, non-linear fog with foggy shader,
1710  *                linear table fog with foggy shader
1711  */
1712 static void fog_with_shader_test(IDirect3DDevice9 *device)
1713 {
1714     HRESULT hr;
1715     DWORD color;
1716     union {
1717         float f;
1718         DWORD i;
1719     } start, end;
1720     unsigned int i, j;
1721
1722     /* basic vertex shader without fog computation ("non foggy") */
1723     static const DWORD vertex_shader_code1[] =
1724     {
1725         0xfffe0101,                                                             /* vs_1_1                       */
1726         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1727         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1728         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1729         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1730         0x0000ffff
1731     };
1732     /* basic vertex shader with reversed fog computation ("foggy") */
1733     static const DWORD vertex_shader_code2[] =
1734     {
1735         0xfffe0101,                                                             /* vs_1_1                        */
1736         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1737         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1738         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1739         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1740         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1741         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1742         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1743         0x0000ffff
1744     };
1745     /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
1746     static const DWORD vertex_shader_code3[] =
1747     {
1748         0xfffe0200,                                                             /* vs_2_0                        */
1749         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1750         0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1751         0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1752         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1753         0x02000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1754         0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1755         0x03000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1756         0x0000ffff
1757     };
1758     /* basic pixel shader */
1759     static const DWORD pixel_shader_code[] =
1760     {
1761         0xffff0101,                                                             /* ps_1_1     */
1762         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0 */
1763         0x0000ffff
1764     };
1765     static const DWORD pixel_shader_code2[] =
1766     {
1767         0xffff0200,                                                             /* ps_2_0     */
1768         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0 */
1769         0x02000001, 0x800f0800, 0x90e40000,                                     /* mov oC0, v0 */
1770         0x0000ffff
1771     };
1772
1773     static struct vertex quad[] = {
1774         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1775         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1776         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1777         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1778     };
1779
1780     static const D3DVERTEXELEMENT9 decl_elements[] = {
1781         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1782         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1783         D3DDECL_END()
1784     };
1785
1786     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1787     IDirect3DVertexShader9      *vertex_shader[4]   = {NULL, NULL, NULL, NULL};
1788     IDirect3DPixelShader9       *pixel_shader[3]    = {NULL, NULL, NULL};
1789
1790     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1791     static const struct test_data_t {
1792         int vshader;
1793         int pshader;
1794         D3DFOGMODE vfog;
1795         D3DFOGMODE tfog;
1796         unsigned int color[11];
1797     } test_data[] = {
1798         /* only pixel shader: */
1799         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1800         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1801         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1802         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1803         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1804         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1805         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1806         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1807         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1808         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1809         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1810         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1811         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1812         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1813         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1814
1815         /* vertex shader */
1816         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1817         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1818          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1819         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1820         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1821         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1822         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1823         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1824         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1825
1826         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1827         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1828         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1829         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1830         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1831         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1832
1833         /* vertex shader and pixel shader */
1834         /* The next 4 tests would read the fog coord output, but it isn't available.
1835          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1836          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1837          * These tests should be disabled if some other hardware behaves differently
1838          */
1839         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1840         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1841         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1842         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1843         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1844         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1845         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1846         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1847         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1848         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1849         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1850         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1851
1852         /* These use the Z coordinate with linear table fog */
1853         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1854         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1855         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1856         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1857         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1858         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1859         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1860         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1861         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1862         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1863         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1864         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1865
1866         /* Non-linear table fog without fog coord */
1867         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1868         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1869         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1870         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1871         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1872         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1873
1874         /* These tests fail on older Nvidia drivers */
1875         /* foggy vertex shader */
1876         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1877         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1878          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1879         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1880         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1881          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1882         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1883         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1884          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1885         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1886         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1887          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1888
1889         {3, 0, D3DFOG_NONE, D3DFOG_NONE,
1890         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1891          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1892         {3, 0, D3DFOG_EXP, D3DFOG_NONE,
1893         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1894          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1895         {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
1896         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1897          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1898         {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1899         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1900          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1901
1902         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1903          * all using the fixed fog-coord linear fog
1904          */
1905         /* vs_1_1 with ps_1_1 */
1906         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1907         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1908          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1909         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1910         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1911          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1912         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1913         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1914          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1915         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1916         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1917          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1918
1919         /* vs_2_0 with ps_1_1 */
1920         {3, 1, D3DFOG_NONE, D3DFOG_NONE,
1921         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1922          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1923         {3, 1, D3DFOG_EXP, D3DFOG_NONE,
1924         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1925          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1926         {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
1927         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1928          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1929         {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1930         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1931          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1932
1933         /* vs_1_1 with ps_2_0 */
1934         {2, 2, D3DFOG_NONE, D3DFOG_NONE,
1935         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1936          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1937         {2, 2, D3DFOG_EXP, D3DFOG_NONE,
1938         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1939          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1940         {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
1941         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1942          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1943         {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
1944         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1945          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1946
1947         /* vs_2_0 with ps_2_0 */
1948         {3, 2, D3DFOG_NONE, D3DFOG_NONE,
1949         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1950          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1951         {3, 2, D3DFOG_EXP, D3DFOG_NONE,
1952         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1953          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1954         {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
1955         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1956          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1957         {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
1958         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1959          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1960
1961         /* These use table fog. Here the shader-provided fog coordinate is
1962          * ignored and the z coordinate used instead
1963          */
1964         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1965         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1966         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1967         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1968         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1969         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1970         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1971         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1972         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1973     };
1974
1975     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1976     start.f=0.1f;
1977     end.f=0.9f;
1978
1979     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1980     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1981     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1982     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1983     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
1984     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1985     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1986     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1987     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
1988     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1989     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1990     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1991
1992     /* Setup initial states: No lighting, fog on, fog color */
1993     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1994     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1995     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1996     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1997     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1998     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1999     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2000     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2001
2002     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2003     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
2004     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2005     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
2006
2007     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
2008     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
2009     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
2010     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
2011     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
2012
2013     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
2014     {
2015         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
2016         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2017         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
2018         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2019         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
2020         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2021         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
2022         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2023
2024         for(j=0; j < 11; j++)
2025         {
2026             /* Don't use the whole zrange to prevent rounding errors */
2027             quad[0].z = 0.001f + (float)j / 10.02f;
2028             quad[1].z = 0.001f + (float)j / 10.02f;
2029             quad[2].z = 0.001f + (float)j / 10.02f;
2030             quad[3].z = 0.001f + (float)j / 10.02f;
2031
2032             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2033             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2034
2035             hr = IDirect3DDevice9_BeginScene(device);
2036             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
2037
2038             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2039             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2040
2041             hr = IDirect3DDevice9_EndScene(device);
2042             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
2043
2044             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
2045             color = getPixelColor(device, 128, 240);
2046             ok(color_match(color, test_data[i].color[j], 13),
2047                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
2048                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
2049
2050             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2051         }
2052     }
2053
2054     /* reset states */
2055     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2056     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2057     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2058     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2059     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2060     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2061     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
2062     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
2063
2064     IDirect3DVertexShader9_Release(vertex_shader[1]);
2065     IDirect3DVertexShader9_Release(vertex_shader[2]);
2066     IDirect3DVertexShader9_Release(vertex_shader[3]);
2067     IDirect3DPixelShader9_Release(pixel_shader[1]);
2068     IDirect3DPixelShader9_Release(pixel_shader[2]);
2069     IDirect3DVertexDeclaration9_Release(vertex_declaration);
2070 }
2071
2072 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
2073     unsigned int i, x, y;
2074     HRESULT hr;
2075     IDirect3DTexture9 *texture[2] = {NULL, NULL};
2076     D3DLOCKED_RECT locked_rect;
2077
2078     /* Generate the textures */
2079     for(i=0; i<2; i++)
2080     {
2081         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
2082                                             D3DPOOL_MANAGED, &texture[i], NULL);
2083         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
2084
2085         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
2086         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2087         for (y = 0; y < 128; ++y)
2088         {
2089             if(i)
2090             { /* Set up black texture with 2x2 texel white spot in the middle */
2091                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2092                 for (x = 0; x < 128; ++x)
2093                 {
2094                     if(y>62 && y<66 && x>62 && x<66)
2095                         *ptr++ = 0xffffffff;
2096                     else
2097                         *ptr++ = 0xff000000;
2098                 }
2099             }
2100             else
2101             { /* Set up a displacement map which points away from the center parallel to the closest axis.
2102                * (if multiplied with bumpenvmat)
2103               */
2104                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2105                 for (x = 0; x < 128; ++x)
2106                 {
2107                     if(abs(x-64)>abs(y-64))
2108                     {
2109                         if(x < 64)
2110                             *ptr++ = 0xc000;
2111                         else
2112                             *ptr++ = 0x4000;
2113                     }
2114                     else
2115                     {
2116                         if(y < 64)
2117                             *ptr++ = 0x0040;
2118                         else
2119                             *ptr++ = 0x00c0;
2120                     }
2121                 }
2122             }
2123         }
2124         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2125         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2126
2127         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2128         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2129
2130         /* Disable texture filtering */
2131         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2132         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2133         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2134         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2135
2136         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2137         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2138         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2139         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2140     }
2141 }
2142
2143 /* test the behavior of the texbem instruction
2144  * with normal 2D and projective 2D textures
2145  */
2146 static void texbem_test(IDirect3DDevice9 *device)
2147 {
2148     HRESULT hr;
2149     DWORD color;
2150     int i;
2151
2152     static const DWORD pixel_shader_code[] = {
2153         0xffff0101,                         /* ps_1_1*/
2154         0x00000042, 0xb00f0000,             /* tex t0*/
2155         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2156         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
2157         0x0000ffff
2158     };
2159     static const DWORD double_texbem_code[] =  {
2160         0xffff0103,                                         /* ps_1_3           */
2161         0x00000042, 0xb00f0000,                             /* tex t0           */
2162         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
2163         0x00000042, 0xb00f0002,                             /* tex t2           */
2164         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
2165         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
2166         0x0000ffff                                          /* end              */
2167     };
2168
2169
2170     static const float quad[][7] = {
2171         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
2172         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
2173         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
2174         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
2175     };
2176     static const float quad_proj[][9] = {
2177         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
2178         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
2179         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
2180         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
2181     };
2182
2183     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
2184         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2185         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2186         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2187         D3DDECL_END()
2188     },{
2189         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2190         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2191         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2192         D3DDECL_END()
2193     } };
2194
2195     /* use asymmetric matrix to test loading */
2196     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
2197
2198     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2199     IDirect3DPixelShader9       *pixel_shader       = NULL;
2200     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
2201     D3DLOCKED_RECT locked_rect;
2202
2203     generate_bumpmap_textures(device);
2204
2205     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2206     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2207     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2208     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2209     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
2210
2211     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2212     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2213
2214     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2215     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2216
2217     for(i=0; i<2; i++)
2218     {
2219         if(i)
2220         {
2221             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
2222             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2223         }
2224
2225         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
2226         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2227         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2228         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2229
2230         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
2231         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2232         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2233         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2234
2235         hr = IDirect3DDevice9_BeginScene(device);
2236         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2237
2238         if(!i)
2239             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2240         else
2241             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
2242         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2243
2244         hr = IDirect3DDevice9_EndScene(device);
2245         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2246
2247         color = getPixelColor(device, 320-32, 240);
2248         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2249         color = getPixelColor(device, 320+32, 240);
2250         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2251         color = getPixelColor(device, 320, 240-32);
2252         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2253         color = getPixelColor(device, 320, 240+32);
2254         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2255
2256         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2257         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2258
2259         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2260         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2261         IDirect3DPixelShader9_Release(pixel_shader);
2262
2263         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2264         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2265         IDirect3DVertexDeclaration9_Release(vertex_declaration);
2266     }
2267
2268     /* clean up */
2269     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2270     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2271
2272     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2273     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2274
2275     for(i=0; i<2; i++)
2276     {
2277         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
2278         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
2279         IDirect3DTexture9_Release(texture); /* For the GetTexture */
2280         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2281         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2282         IDirect3DTexture9_Release(texture);
2283     }
2284
2285     /* Test double texbem */
2286     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
2287     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2288     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
2289     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2290     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
2291     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2292     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
2293     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2294
2295     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
2296     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2297     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
2298     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
2299
2300     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2301     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2302
2303     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
2304     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2305     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
2306     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
2307     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
2308     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2309
2310     {
2311         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
2312 #define tex  0x00ff0000
2313 #define tex1 0x0000ff00
2314 #define origin 0x000000ff
2315         static const DWORD pixel_data[] = {
2316             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2317             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2318             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2319             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2320             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
2321             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2322             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2323             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2324         };
2325 #undef tex1
2326 #undef tex2
2327 #undef origin
2328
2329         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
2330         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2331         for(i = 0; i < 8; i++) {
2332             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
2333         }
2334         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
2335         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2336     }
2337
2338     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2339     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2340     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
2341     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2342     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
2343     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2344     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2345     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2346     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2347     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2348     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2349     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2350
2351     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
2352     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
2353     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2354     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2355     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2356     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2357     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2358     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2359     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2360     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2361
2362     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2363     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2364     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2365     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2366     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2367     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2368     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2369     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2370     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2371     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2372
2373     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2374     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2375     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2376     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2377     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2378     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2379     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2380     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2381     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2382     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2383     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2384     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2385     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2386     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2387     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2388     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2389
2390     hr = IDirect3DDevice9_BeginScene(device);
2391     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2392     if(SUCCEEDED(hr)) {
2393         static const float double_quad[] = {
2394             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2395              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2396             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2397              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2398         };
2399
2400         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2401         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2402         hr = IDirect3DDevice9_EndScene(device);
2403         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2404     }
2405     color = getPixelColor(device, 320, 240);
2406     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2407
2408     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2409     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2410     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2411     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2412     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2413     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2414     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2415     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2416     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2417     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2418
2419     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2420     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2421
2422     IDirect3DPixelShader9_Release(pixel_shader);
2423     IDirect3DTexture9_Release(texture);
2424     IDirect3DTexture9_Release(texture1);
2425     IDirect3DTexture9_Release(texture2);
2426 }
2427
2428 static void z_range_test(IDirect3DDevice9 *device)
2429 {
2430     const struct vertex quad[] =
2431     {
2432         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2433         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2434         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2435         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2436     };
2437     const struct vertex quad2[] =
2438     {
2439         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2440         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2441         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2442         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2443     };
2444
2445     const struct tvertex quad3[] =
2446     {
2447         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2448         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2449         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2450         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2451     };
2452     const struct tvertex quad4[] =
2453     {
2454         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2455         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2456         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2457         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2458     };
2459     HRESULT hr;
2460     DWORD color;
2461     IDirect3DVertexShader9 *shader;
2462     IDirect3DVertexDeclaration9 *decl;
2463     D3DCAPS9 caps;
2464     const DWORD shader_code[] = {
2465         0xfffe0101,                                     /* vs_1_1           */
2466         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2467         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2468         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2469         0x0000ffff                                      /* end              */
2470     };
2471     static const D3DVERTEXELEMENT9 decl_elements[] = {
2472         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2473         D3DDECL_END()
2474     };
2475
2476     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2477
2478     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2479      * then call Present. Then clear the color buffer to make sure it has some defined content
2480      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2481      * by the depth value.
2482      */
2483     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2484     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2485     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2486     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2487     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2488     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2489
2490     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2491     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2492     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2493     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2494     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2495     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2496     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2497     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2498     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2499     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2500
2501     hr = IDirect3DDevice9_BeginScene(device);
2502     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2503     if(hr == D3D_OK)
2504     {
2505         /* Test the untransformed vertex path */
2506         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2507         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2508         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2509         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2510         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2511         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2512
2513         /* Test the transformed vertex path */
2514         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2515         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2516
2517         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2518         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2519         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2520         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2521         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2522         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2523
2524         hr = IDirect3DDevice9_EndScene(device);
2525         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2526     }
2527
2528     /* Do not test the exact corner pixels, but go pretty close to them */
2529
2530     /* Clipped because z > 1.0 */
2531     color = getPixelColor(device, 28, 238);
2532     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2533     color = getPixelColor(device, 28, 241);
2534     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2535     {
2536         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2537     }
2538     else
2539     {
2540         ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2541     }
2542
2543     /* Not clipped, > z buffer clear value(0.75) */
2544     color = getPixelColor(device, 31, 238);
2545     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2546     color = getPixelColor(device, 31, 241);
2547     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2548     color = getPixelColor(device, 100, 238);
2549     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2550     color = getPixelColor(device, 100, 241);
2551     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2552
2553     /* Not clipped, < z buffer clear value */
2554     color = getPixelColor(device, 104, 238);
2555     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2556     color = getPixelColor(device, 104, 241);
2557     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2558     color = getPixelColor(device, 318, 238);
2559     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2560     color = getPixelColor(device, 318, 241);
2561     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2562
2563     /* Clipped because z < 0.0 */
2564     color = getPixelColor(device, 321, 238);
2565     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2566     color = getPixelColor(device, 321, 241);
2567     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2568     {
2569         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2570     }
2571     else
2572     {
2573         ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2574     }
2575
2576     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2577     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2578
2579     /* Test the shader path */
2580     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2581         skip("Vertex shaders not supported\n");
2582         goto out;
2583     }
2584     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2585     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2586     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2587     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2588
2589     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2590
2591     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2592     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2593     hr = IDirect3DDevice9_SetVertexShader(device, shader);
2594     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2595
2596     hr = IDirect3DDevice9_BeginScene(device);
2597     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2598     if(hr == D3D_OK)
2599     {
2600         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2601         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2602         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2603         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2604         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2605         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2606         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2607         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2608         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2609         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2610
2611         hr = IDirect3DDevice9_EndScene(device);
2612         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2613     }
2614
2615     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2616     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2617     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2618     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2619
2620     IDirect3DVertexDeclaration9_Release(decl);
2621     IDirect3DVertexShader9_Release(shader);
2622
2623     /* Z < 1.0 */
2624     color = getPixelColor(device, 28, 238);
2625     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2626
2627     /* 1.0 < z < 0.75 */
2628     color = getPixelColor(device, 31, 238);
2629     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2630     color = getPixelColor(device, 100, 238);
2631     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2632
2633     /* 0.75 < z < 0.0 */
2634     color = getPixelColor(device, 104, 238);
2635     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2636     color = getPixelColor(device, 318, 238);
2637     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2638
2639     /* 0.0 < z */
2640     color = getPixelColor(device, 321, 238);
2641     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2642
2643     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2644     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2645
2646     out:
2647     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2648     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2649     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2650     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2651     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2652     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2653 }
2654
2655 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2656 {
2657     D3DSURFACE_DESC desc;
2658     D3DLOCKED_RECT l;
2659     HRESULT hr;
2660     unsigned int x, y;
2661     DWORD *mem;
2662
2663     memset(&desc, 0, sizeof(desc));
2664     memset(&l, 0, sizeof(l));
2665     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2666     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2667     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2668     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2669     if(FAILED(hr)) return;
2670
2671     for(y = 0; y < desc.Height; y++)
2672     {
2673         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2674         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2675         {
2676             mem[x] = color;
2677         }
2678     }
2679     hr = IDirect3DSurface9_UnlockRect(surface);
2680     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2681 }
2682
2683 /* This tests a variety of possible StretchRect() situations */
2684 static void stretchrect_test(IDirect3DDevice9 *device)
2685 {
2686     HRESULT hr;
2687     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2688     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2689     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2690     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2691     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2692     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2693     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2694     IDirect3DSurface9 *orig_rt = NULL;
2695     IDirect3DSurface9 *backbuffer = NULL;
2696     DWORD color;
2697
2698     RECT src_rect64 = {0, 0, 64, 64};
2699     RECT src_rect64_flipy = {0, 64, 64, 0};
2700     RECT dst_rect64 = {0, 0, 64, 64};
2701     RECT dst_rect64_flipy = {0, 64, 64, 0};
2702
2703     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2704     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2705     if(!orig_rt) {
2706         goto out;
2707     }
2708
2709     /* Create our temporary surfaces in system memory */
2710     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2711     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2712     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2713     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2714
2715     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2716     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2717     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2718     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2719     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2720     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2721     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2722
2723     /* Create render target surfaces */
2724     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2725     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2726     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2727     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2728     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2729     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2730     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2731     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2732
2733     /* Create render target textures */
2734     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2735     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2736     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2737     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2738     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2739     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2740     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2741     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2742     if (tex_rt32) {
2743         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2744         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2745     }
2746     if (tex_rt64) {
2747         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2748         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2749     }
2750     if (tex_rt_dest64) {
2751         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2752         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2753     }
2754     if (tex_rt_dest640_480) {
2755         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2756         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2757     }
2758
2759     /* Create regular textures in D3DPOOL_DEFAULT */
2760     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2761     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2762     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2763     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2764     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2765     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2766     if (tex32) {
2767         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2768         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2769     }
2770     if (tex64) {
2771         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2772         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2773     }
2774     if (tex_dest64) {
2775         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2776         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2777     }
2778
2779     /*********************************************************************
2780      * Tests for when the source parameter is an offscreen plain surface *
2781      *********************************************************************/
2782
2783     /* Fill the offscreen 64x64 surface with green */
2784     if (surf_offscreen64)
2785         fill_surface(surf_offscreen64, 0xff00ff00);
2786
2787     /* offscreenplain ==> offscreenplain, same size */
2788     if(surf_offscreen64 && surf_offscreen_dest64) {
2789         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2790         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2791
2792         if (hr == D3D_OK) {
2793             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2794             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2795         }
2796
2797         /* Blit without scaling */
2798         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2799         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2800
2801         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2802         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2803         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2804
2805         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2806         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2807         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2808     }
2809
2810     /* offscreenplain ==> rendertarget texture, same size */
2811     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2812         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2813         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2814
2815         /* We can't lock rendertarget textures, so copy to our temp surface first */
2816         if (hr == D3D_OK) {
2817             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2818             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2819         }
2820
2821         if (hr == D3D_OK) {
2822             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2823             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2824         }
2825
2826         /* Blit without scaling */
2827         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2828         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2829
2830         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2831         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2832         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2833
2834         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2835         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2836         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2837     }
2838
2839     /* offscreenplain ==> rendertarget surface, same size */
2840     if(surf_offscreen64 && surf_rt_dest64) {
2841         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2842         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2843
2844         if (hr == D3D_OK) {
2845             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2846             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2847         }
2848
2849         /* Blit without scaling */
2850         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2851         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2852
2853         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2854         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2855         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2856
2857         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2858         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2859         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2860     }
2861
2862     /* offscreenplain ==> texture, same size (should fail) */
2863     if(surf_offscreen64 && surf_tex_dest64) {
2864         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2865         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2866     }
2867
2868     /* Fill the smaller offscreen surface with red */
2869     fill_surface(surf_offscreen32, 0xffff0000);
2870
2871     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2872     if(surf_offscreen32 && surf_offscreen64) {
2873         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2874         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2875     }
2876
2877     /* offscreenplain ==> rendertarget texture, scaling */
2878     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2879         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2880         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2881
2882         /* We can't lock rendertarget textures, so copy to our temp surface first */
2883         if (hr == D3D_OK) {
2884             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2885             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2886         }
2887
2888         if (hr == D3D_OK) {
2889             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2890             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2891         }
2892     }
2893
2894     /* offscreenplain ==> rendertarget surface, scaling */
2895     if(surf_offscreen32 && surf_rt_dest64) {
2896         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2897         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2898
2899         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2900         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2901     }
2902
2903     /* offscreenplain ==> texture, scaling (should fail) */
2904     if(surf_offscreen32 && surf_tex_dest64) {
2905         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2906         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2907     }
2908
2909     /************************************************************
2910      * Tests for when the source parameter is a regular texture *
2911      ************************************************************/
2912
2913     /* Fill the surface of the regular texture with blue */
2914     if (surf_tex64 && surf_temp64) {
2915         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2916         fill_surface(surf_temp64, 0xff0000ff);
2917         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2918         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2919     }
2920
2921     /* texture ==> offscreenplain, same size */
2922     if(surf_tex64 && surf_offscreen64) {
2923         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2924         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2925     }
2926
2927     /* texture ==> rendertarget texture, same size */
2928     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2929         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2930         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2931
2932         /* We can't lock rendertarget textures, so copy to our temp surface first */
2933         if (hr == D3D_OK) {
2934             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2935             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2936         }
2937
2938         if (hr == D3D_OK) {
2939             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2940             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2941         }
2942
2943         /* Blit without scaling */
2944         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2945         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2946
2947         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2948         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2949         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2950
2951         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2952         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2953         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2954     }
2955
2956     /* texture ==> rendertarget surface, same size */
2957     if(surf_tex64 && surf_rt_dest64) {
2958         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2959         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2960
2961         if (hr == D3D_OK) {
2962             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2963             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2964         }
2965
2966         /* Blit without scaling */
2967         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2968         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2969
2970         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2971         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2972         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2973
2974         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2975         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2976         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2977     }
2978
2979     /* texture ==> texture, same size (should fail) */
2980     if(surf_tex64 && surf_tex_dest64) {
2981         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2982         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2983     }
2984
2985     /* Fill the surface of the smaller regular texture with red */
2986     if (surf_tex32 && surf_temp32) {
2987         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2988         fill_surface(surf_temp32, 0xffff0000);
2989         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2990         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2991     }
2992
2993     /* texture ==> offscreenplain, scaling (should fail) */
2994     if(surf_tex32 && surf_offscreen64) {
2995         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2996         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2997     }
2998
2999     /* texture ==> rendertarget texture, scaling */
3000     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
3001         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
3002         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3003
3004         /* We can't lock rendertarget textures, so copy to our temp surface first */
3005         if (hr == D3D_OK) {
3006             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3007             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3008         }
3009
3010         if (hr == D3D_OK) {
3011             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3012             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3013         }
3014     }
3015
3016     /* texture ==> rendertarget surface, scaling */
3017     if(surf_tex32 && surf_rt_dest64) {
3018         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
3019         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3020
3021         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3022         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3023     }
3024
3025     /* texture ==> texture, scaling (should fail) */
3026     if(surf_tex32 && surf_tex_dest64) {
3027         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
3028         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3029     }
3030
3031     /*****************************************************************
3032      * Tests for when the source parameter is a rendertarget texture *
3033      *****************************************************************/
3034
3035     /* Fill the surface of the rendertarget texture with white */
3036     if (surf_tex_rt64 && surf_temp64) {
3037         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
3038         fill_surface(surf_temp64, 0xffffffff);
3039         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
3040         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3041     }
3042
3043     /* rendertarget texture ==> offscreenplain, same size */
3044     if(surf_tex_rt64 && surf_offscreen64) {
3045         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
3046         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3047     }
3048
3049     /* rendertarget texture ==> rendertarget texture, same size */
3050     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3051         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3052         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3053
3054         /* We can't lock rendertarget textures, so copy to our temp surface first */
3055         if (hr == D3D_OK) {
3056             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3057             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3058         }
3059
3060         if (hr == D3D_OK) {
3061             color = getPixelColorFromSurface(surf_temp64, 32, 32);
3062             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
3063         }
3064
3065         /* Blit without scaling */
3066         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3067         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3068
3069         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3070         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3071         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3072
3073         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3074         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3075         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3076     }
3077
3078     /* rendertarget texture ==> rendertarget surface, same size */
3079     if(surf_tex_rt64 && surf_rt_dest64) {
3080         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
3081         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3082
3083         if (hr == D3D_OK) {
3084             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3085             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
3086         }
3087
3088         /* Blit without scaling */
3089         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3090         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3091
3092         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3093         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
3094         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3095
3096         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3097         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3098         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3099     }
3100
3101     /* rendertarget texture ==> texture, same size (should fail) */
3102     if(surf_tex_rt64 && surf_tex_dest64) {
3103         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
3104         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3105     }
3106
3107     /* Fill the surface of the smaller rendertarget texture with red */
3108     if (surf_tex_rt32 && surf_temp32) {
3109         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
3110         fill_surface(surf_temp32, 0xffff0000);
3111         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3112         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3113     }
3114
3115     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
3116     if(surf_tex_rt32 && surf_offscreen64) {
3117         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
3118         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3119     }
3120
3121     /* rendertarget texture ==> rendertarget texture, scaling */
3122     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3123         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3124         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3125
3126         /* We can't lock rendertarget textures, so copy to our temp surface first */
3127         if (hr == D3D_OK) {
3128             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3129             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3130         }
3131
3132         if (hr == D3D_OK) {
3133             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3134             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3135         }
3136     }
3137
3138     /* rendertarget texture ==> rendertarget surface, scaling */
3139     if(surf_tex_rt32 && surf_rt_dest64) {
3140         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
3141         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3142
3143         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3144         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3145     }
3146
3147     /* rendertarget texture ==> texture, scaling (should fail) */
3148     if(surf_tex_rt32 && surf_tex_dest64) {
3149         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
3150         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3151     }
3152
3153     /*****************************************************************
3154      * Tests for when the source parameter is a rendertarget surface *
3155      *****************************************************************/
3156
3157     /* Fill the surface of the rendertarget surface with black */
3158     if (surf_rt64)
3159         fill_surface(surf_rt64, 0xff000000);
3160
3161     /* rendertarget texture ==> offscreenplain, same size */
3162     if(surf_rt64 && surf_offscreen64) {
3163         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
3164         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3165     }
3166
3167     /* rendertarget surface ==> rendertarget texture, same size */
3168     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3169         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3170         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3171
3172         /* We can't lock rendertarget textures, so copy to our temp surface first */
3173         if (hr == D3D_OK) {
3174             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3175             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3176         }
3177
3178         if (hr == D3D_OK) {
3179             color = getPixelColorFromSurface(surf_temp64, 32, 32);
3180             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3181         }
3182
3183         /* Blit without scaling */
3184         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3185         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3186
3187         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3188         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3189         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3190
3191         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3192         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3193         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3194     }
3195
3196     /* rendertarget surface ==> rendertarget surface, same size */
3197     if(surf_rt64 && surf_rt_dest64) {
3198         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
3199         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3200
3201         if (hr == D3D_OK) {
3202             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3203             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3204         }
3205
3206         /* Blit without scaling */
3207         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3208         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3209
3210         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3211         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
3212         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3213
3214         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3215         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3216         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3217     }
3218
3219     /* rendertarget surface ==> texture, same size (should fail) */
3220     if(surf_rt64 && surf_tex_dest64) {
3221         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
3222         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3223     }
3224
3225     /* Fill the surface of the smaller rendertarget texture with red */
3226     if (surf_rt32)
3227         fill_surface(surf_rt32, 0xffff0000);
3228
3229     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
3230     if(surf_rt32 && surf_offscreen64) {
3231         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
3232         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3233     }
3234
3235     /* rendertarget surface ==> rendertarget texture, scaling */
3236     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3237         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3238         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3239
3240         /* We can't lock rendertarget textures, so copy to our temp surface first */
3241         if (hr == D3D_OK) {
3242             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3243             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3244         }
3245
3246         if (hr == D3D_OK) {
3247             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3248             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3249         }
3250     }
3251
3252     /* rendertarget surface ==> rendertarget surface, scaling */
3253     if(surf_rt32 && surf_rt_dest64) {
3254         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
3255         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3256
3257         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3258         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3259     }
3260
3261     /* rendertarget surface ==> texture, scaling (should fail) */
3262     if(surf_rt32 && surf_tex_dest64) {
3263         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
3264         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3265     }
3266
3267     /* backbuffer ==> surface tests (no scaling) */
3268     if(backbuffer && surf_tex_rt_dest640_480)
3269     {
3270         RECT src_rect = {0, 0, 640, 480};
3271         RECT src_rect_flipy = {0, 480, 640, 0};
3272         RECT dst_rect = {0, 0, 640, 480};
3273         RECT dst_rect_flipy = {0, 480, 640, 0};
3274
3275         /* Blit with NULL rectangles */
3276         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
3277         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
3278
3279         /* Blit without scaling */
3280         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
3281         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3282
3283         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3284         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
3285         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3286
3287         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3288         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
3289         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3290     }
3291
3292     /* TODO: Test format conversions */
3293
3294
3295 out:
3296     /* Clean up */
3297     if (backbuffer)
3298         IDirect3DSurface9_Release(backbuffer);
3299     if (surf_rt32)
3300         IDirect3DSurface9_Release(surf_rt32);
3301     if (surf_rt64)
3302         IDirect3DSurface9_Release(surf_rt64);
3303     if (surf_rt_dest64)
3304         IDirect3DSurface9_Release(surf_rt_dest64);
3305     if (surf_temp32)
3306         IDirect3DSurface9_Release(surf_temp32);
3307     if (surf_temp64)
3308         IDirect3DSurface9_Release(surf_temp64);
3309     if (surf_offscreen32)
3310         IDirect3DSurface9_Release(surf_offscreen32);
3311     if (surf_offscreen64)
3312         IDirect3DSurface9_Release(surf_offscreen64);
3313     if (surf_offscreen_dest64)
3314         IDirect3DSurface9_Release(surf_offscreen_dest64);
3315
3316     if (tex_rt32) {
3317         if (surf_tex_rt32)
3318             IDirect3DSurface9_Release(surf_tex_rt32);
3319         IDirect3DTexture9_Release(tex_rt32);
3320     }
3321     if (tex_rt64) {
3322         if (surf_tex_rt64)
3323             IDirect3DSurface9_Release(surf_tex_rt64);
3324         IDirect3DTexture9_Release(tex_rt64);
3325     }
3326     if (tex_rt_dest64) {
3327         if (surf_tex_rt_dest64)
3328             IDirect3DSurface9_Release(surf_tex_rt_dest64);
3329         IDirect3DTexture9_Release(tex_rt_dest64);
3330     }
3331     if (tex_rt_dest640_480) {
3332         if (surf_tex_rt_dest640_480)
3333             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
3334         IDirect3DTexture9_Release(tex_rt_dest640_480);
3335     }
3336     if (tex32) {
3337         if (surf_tex32)
3338             IDirect3DSurface9_Release(surf_tex32);
3339         IDirect3DTexture9_Release(tex32);
3340     }
3341     if (tex64) {
3342         if (surf_tex64)
3343             IDirect3DSurface9_Release(surf_tex64);
3344         IDirect3DTexture9_Release(tex64);
3345     }
3346     if (tex_dest64) {
3347         if (surf_tex_dest64)
3348             IDirect3DSurface9_Release(surf_tex_dest64);
3349         IDirect3DTexture9_Release(tex_dest64);
3350     }
3351
3352     if (orig_rt) {
3353         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3354         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3355         IDirect3DSurface9_Release(orig_rt);
3356     }
3357 }
3358
3359 static void maxmip_test(IDirect3DDevice9 *device)
3360 {
3361     IDirect3DTexture9 *texture = NULL;
3362     IDirect3DSurface9 *surface = NULL;
3363     HRESULT hr;
3364     DWORD color;
3365     static const struct
3366     {
3367         struct
3368         {
3369             float x, y, z;
3370             float s, t;
3371         }
3372         v[4];
3373     }
3374     quads[] =
3375     {
3376         {{
3377             {-1.0, -1.0,  0.0,  0.0,  0.0},
3378             {-1.0,  0.0,  0.0,  0.0,  1.0},
3379             { 0.0, -1.0,  0.0,  1.0,  0.0},
3380             { 0.0,  0.0,  0.0,  1.0,  1.0},
3381         }},
3382         {{
3383             { 0.0, -1.0,  0.0,  0.0,  0.0},
3384             { 0.0,  0.0,  0.0,  0.0,  1.0},
3385             { 1.0, -1.0,  0.0,  1.0,  0.0},
3386             { 1.0,  0.0,  0.0,  1.0,  1.0},
3387         }},
3388         {{
3389             { 0.0,  0.0,  0.0,  0.0,  0.0},
3390             { 0.0,  1.0,  0.0,  0.0,  1.0},
3391             { 1.0,  0.0,  0.0,  1.0,  0.0},
3392             { 1.0,  1.0,  0.0,  1.0,  1.0},
3393         }},
3394         {{
3395             {-1.0,  0.0,  0.0,  0.0,  0.0},
3396             {-1.0,  1.0,  0.0,  0.0,  1.0},
3397             { 0.0,  0.0,  0.0,  1.0,  0.0},
3398             { 0.0,  1.0,  0.0,  1.0,  1.0},
3399         }},
3400     };
3401
3402     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3403                                         &texture, NULL);
3404     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3405     if(!texture)
3406     {
3407         skip("Failed to create test texture\n");
3408         return;
3409     }
3410
3411     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3412     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3413     fill_surface(surface, 0xffff0000);
3414     IDirect3DSurface9_Release(surface);
3415     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3416     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3417     fill_surface(surface, 0xff00ff00);
3418     IDirect3DSurface9_Release(surface);
3419     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3420     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3421     fill_surface(surface, 0xff0000ff);
3422     IDirect3DSurface9_Release(surface);
3423
3424     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3425     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3426     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3427     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3428
3429     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3430     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3431
3432     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3433     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3434
3435     hr = IDirect3DDevice9_BeginScene(device);
3436     if(SUCCEEDED(hr))
3437     {
3438         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3439         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3440         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3441         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3442
3443         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3444         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3445         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3446         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3447
3448         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3449         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3450         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3451         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3452
3453         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3454         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3455         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3456         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3457         hr = IDirect3DDevice9_EndScene(device);
3458         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3459     }
3460
3461     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3462     color = getPixelColor(device, 160, 360);
3463     ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3464     color = getPixelColor(device, 480, 360);
3465     ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3466     color = getPixelColor(device, 480, 120);
3467     ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3468     color = getPixelColor(device, 160, 120);
3469     ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3470     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3471     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3472
3473     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3474     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3475
3476     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3477     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3478
3479     hr = IDirect3DDevice9_BeginScene(device);
3480     if(SUCCEEDED(hr))
3481     {
3482         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3483         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3484         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3485         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3486
3487         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3488         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3489         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3490         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3491
3492         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3493         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3494         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3495         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3496
3497         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3498         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3499         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3500         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3501         hr = IDirect3DDevice9_EndScene(device);
3502         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3503     }
3504
3505     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3506      * level 3 (> levels in texture) samples from the highest level in the
3507      * texture (level 2). */
3508     color = getPixelColor(device, 160, 360);
3509     ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3510     color = getPixelColor(device, 480, 360);
3511     ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3512     color = getPixelColor(device, 480, 120);
3513     ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3514     color = getPixelColor(device, 160, 120);
3515     ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3516     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3517     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3518
3519     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3520     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3521
3522     hr = IDirect3DDevice9_BeginScene(device);
3523     if(SUCCEEDED(hr))
3524     {
3525         DWORD ret;
3526
3527         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3528         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3529         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3530         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3531         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3532         ret = IDirect3DTexture9_SetLOD(texture, 1);
3533         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3534         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3535         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3536
3537         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3538         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3539         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3540         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3541         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3542         ret = IDirect3DTexture9_SetLOD(texture, 2);
3543         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3544         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3545         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3546
3547         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3548         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3549         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3550         ret = IDirect3DTexture9_SetLOD(texture, 1);
3551         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3552         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3553         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3554
3555         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3556         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3557         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3558         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3559         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3560         ret = IDirect3DTexture9_SetLOD(texture, 1);
3561         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3562         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3563         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3564         hr = IDirect3DDevice9_EndScene(device);
3565         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3566     }
3567
3568     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3569      * level 3 (> levels in texture) samples from the highest level in the
3570      * texture (level 2). */
3571     color = getPixelColor(device, 160, 360);
3572     ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3573     color = getPixelColor(device, 480, 360);
3574     ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3575     color = getPixelColor(device, 480, 120);
3576     ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3577     color = getPixelColor(device, 160, 120);
3578     ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3579
3580     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3581     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3582
3583     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3584     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3585     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3586     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3587     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3588     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3589     IDirect3DTexture9_Release(texture);
3590 }
3591
3592 static void release_buffer_test(IDirect3DDevice9 *device)
3593 {
3594     IDirect3DVertexBuffer9 *vb = NULL;
3595     IDirect3DIndexBuffer9 *ib = NULL;
3596     HRESULT hr;
3597     BYTE *data;
3598     LONG ref;
3599
3600     static const struct vertex quad[] = {
3601         {-1.0,      -1.0,       0.1,        0xffff0000},
3602         {-1.0,       1.0,       0.1,        0xffff0000},
3603         { 1.0,       1.0,       0.1,        0xffff0000},
3604
3605         {-1.0,      -1.0,       0.1,        0xff00ff00},
3606         {-1.0,       1.0,       0.1,        0xff00ff00},
3607         { 1.0,       1.0,       0.1,        0xff00ff00}
3608     };
3609     short indices[] = {3, 4, 5};
3610
3611     /* Index and vertex buffers should always be creatable */
3612     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3613                                               D3DPOOL_MANAGED, &vb, NULL);
3614     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3615     if(!vb) {
3616         skip("Failed to create a vertex buffer\n");
3617         return;
3618     }
3619     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3620     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3621     if(!ib) {
3622         skip("Failed to create an index buffer\n");
3623         return;
3624     }
3625
3626     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3627     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3628     memcpy(data, quad, sizeof(quad));
3629     hr = IDirect3DVertexBuffer9_Unlock(vb);
3630     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3631
3632     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3633     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3634     memcpy(data, indices, sizeof(indices));
3635     hr = IDirect3DIndexBuffer9_Unlock(ib);
3636     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3637
3638     hr = IDirect3DDevice9_SetIndices(device, ib);
3639     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3640     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3641     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3642     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3643     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3644
3645     /* Now destroy the bound index buffer and draw again */
3646     ref = IDirect3DIndexBuffer9_Release(ib);
3647     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3648
3649     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3650     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3651
3652     hr = IDirect3DDevice9_BeginScene(device);
3653     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3654     if(SUCCEEDED(hr))
3655     {
3656         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3657          * making assumptions about the indices or vertices
3658          */
3659         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3660         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3661         hr = IDirect3DDevice9_EndScene(device);
3662         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3663     }
3664
3665     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3666     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3667
3668     hr = IDirect3DDevice9_SetIndices(device, NULL);
3669     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3670     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3671     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3672
3673     /* Index buffer was already destroyed as part of the test */
3674     IDirect3DVertexBuffer9_Release(vb);
3675 }
3676
3677 static void float_texture_test(IDirect3DDevice9 *device)
3678 {
3679     IDirect3D9 *d3d = NULL;
3680     HRESULT hr;
3681     IDirect3DTexture9 *texture = NULL;
3682     D3DLOCKED_RECT lr;
3683     float *data;
3684     DWORD color;
3685     float quad[] = {
3686         -1.0,      -1.0,       0.1,     0.0,    0.0,
3687         -1.0,       1.0,       0.1,     0.0,    1.0,
3688          1.0,      -1.0,       0.1,     1.0,    0.0,
3689          1.0,       1.0,       0.1,     1.0,    1.0,
3690     };
3691
3692     memset(&lr, 0, sizeof(lr));
3693     IDirect3DDevice9_GetDirect3D(device, &d3d);
3694     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3695                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3696         skip("D3DFMT_R32F textures not supported\n");
3697         goto out;
3698     }
3699
3700     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3701                                         D3DPOOL_MANAGED, &texture, NULL);
3702     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3703     if(!texture) {
3704         skip("Failed to create R32F texture\n");
3705         goto out;
3706     }
3707
3708     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3709     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3710     data = lr.pBits;
3711     *data = 0.0;
3712     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3713     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3714
3715     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3716     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3717
3718     hr = IDirect3DDevice9_BeginScene(device);
3719     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3720     if(SUCCEEDED(hr))
3721     {
3722         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3723         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3724
3725         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3726         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3727
3728         hr = IDirect3DDevice9_EndScene(device);
3729         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3730     }
3731     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3732     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3733
3734     color = getPixelColor(device, 240, 320);
3735     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3736
3737     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3738     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3739
3740 out:
3741     if(texture) IDirect3DTexture9_Release(texture);
3742     IDirect3D9_Release(d3d);
3743 }
3744
3745 static void g16r16_texture_test(IDirect3DDevice9 *device)
3746 {
3747     IDirect3D9 *d3d = NULL;
3748     HRESULT hr;
3749     IDirect3DTexture9 *texture = NULL;
3750     D3DLOCKED_RECT lr;
3751     DWORD *data;
3752     DWORD color;
3753     float quad[] = {
3754        -1.0,      -1.0,       0.1,     0.0,    0.0,
3755        -1.0,       1.0,       0.1,     0.0,    1.0,
3756         1.0,      -1.0,       0.1,     1.0,    0.0,
3757         1.0,       1.0,       0.1,     1.0,    1.0,
3758     };
3759
3760     memset(&lr, 0, sizeof(lr));
3761     IDirect3DDevice9_GetDirect3D(device, &d3d);
3762     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3763        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3764            skip("D3DFMT_G16R16 textures not supported\n");
3765            goto out;
3766     }
3767
3768     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3769                                         D3DPOOL_MANAGED, &texture, NULL);
3770     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3771     if(!texture) {
3772         skip("Failed to create D3DFMT_G16R16 texture\n");
3773         goto out;
3774     }
3775
3776     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3777     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3778     data = lr.pBits;
3779     *data = 0x0f00f000;
3780     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3781     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3782
3783     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3784     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3785
3786     hr = IDirect3DDevice9_BeginScene(device);
3787     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3788     if(SUCCEEDED(hr))
3789     {
3790         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3791         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3792
3793         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3794         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3795
3796         hr = IDirect3DDevice9_EndScene(device);
3797         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3798     }
3799     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3800     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3801
3802     color = getPixelColor(device, 240, 320);
3803     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3804        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3805
3806     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3807     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3808
3809 out:
3810     if(texture) IDirect3DTexture9_Release(texture);
3811     IDirect3D9_Release(d3d);
3812 }
3813
3814 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
3815 {
3816     LONG x_coords[2][2] =
3817     {
3818         {r.left - 1, r.left + 1},
3819         {r.right + 1, r.right - 1},
3820     };
3821     LONG y_coords[2][2] =
3822     {
3823         {r.top - 1, r.top + 1},
3824         {r.bottom + 1, r.bottom - 1}
3825     };
3826     unsigned int i, j, x_side, y_side;
3827
3828     for (i = 0; i < 2; ++i)
3829     {
3830         for (j = 0; j < 2; ++j)
3831         {
3832             for (x_side = 0; x_side < 2; ++x_side)
3833             {
3834                 for (y_side = 0; y_side < 2; ++y_side)
3835                 {
3836                     unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
3837                     DWORD color;
3838                     DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
3839
3840                     color = getPixelColor(device, x, y);
3841                     ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
3842                             message, x, y, color, expected);
3843                 }
3844             }
3845         }
3846     }
3847 }
3848
3849 struct projected_textures_test_run
3850 {
3851     const char *message;
3852     DWORD flags;
3853     IDirect3DVertexDeclaration9 *decl;
3854     BOOL vs, ps;
3855     RECT rect;
3856 };
3857
3858 static void projected_textures_test(IDirect3DDevice9 *device,
3859         struct projected_textures_test_run tests[4])
3860 {
3861     unsigned int i;
3862
3863     static const DWORD vertex_shader[] =
3864     {
3865         0xfffe0101,                                     /* vs_1_1           */
3866         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
3867         0x0000001f, 0x80000005, 0x900f0001,             /* dcl_texcoord0 v1 */
3868         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
3869         0x00000001, 0xe00f0000, 0x90e40001,             /* mov oT0, v1      */
3870         0x0000ffff                                      /* end              */
3871     };
3872     static const DWORD pixel_shader[] =
3873     {
3874         0xffff0103,                                     /* ps_1_3           */
3875         0x00000042, 0xb00f0000,                         /* tex t0           */
3876         0x00000001, 0x800f0000, 0xb0e40000,             /* mov r0, t0       */
3877         0x0000ffff                                      /* end              */
3878     };
3879     IDirect3DVertexShader9 *vs = NULL;
3880     IDirect3DPixelShader9 *ps = NULL;
3881     HRESULT hr;
3882
3883     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
3884     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
3885     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
3886     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3887
3888     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
3889     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3890
3891     hr = IDirect3DDevice9_BeginScene(device);
3892     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3893     if (FAILED(hr))
3894         return;
3895
3896     for (i = 0; i < 4; ++i)
3897     {
3898         DWORD value = 0xdeadbeef;
3899         static const float proj_quads[] =
3900         {
3901             -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3902              0.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3903             -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3904              0.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3905
3906              0.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3907              1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3908              0.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3909              1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3910
3911             -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3912              0.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3913             -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3914              0.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3915
3916              0.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3917              1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3918              0.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3919              1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3920         };
3921
3922         if (tests[i].vs)
3923             hr = IDirect3DDevice9_SetVertexShader(device, vs);
3924         else
3925             hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3926         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
3927         if (tests[i].ps)
3928             hr = IDirect3DDevice9_SetPixelShader(device, ps);
3929         else
3930             hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3931         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3932
3933         hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
3934         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3935
3936         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
3937         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3938         hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
3939         ok(SUCCEEDED(hr) && value == tests[i].flags,
3940                 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
3941
3942         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
3943                 &proj_quads[i * 4 * 7], 7 * sizeof(float));
3944         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3945     }
3946
3947     hr = IDirect3DDevice9_EndScene(device);
3948     ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3949
3950     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3951     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3952     IDirect3DVertexShader9_Release(vs);
3953     IDirect3DPixelShader9_Release(ps);
3954
3955     for (i = 0; i < 4; ++i)
3956         check_rect(device, tests[i].rect, tests[i].message);
3957
3958     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3959     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3960 }
3961
3962 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3963 {
3964     HRESULT hr;
3965     IDirect3D9 *d3d;
3966     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3967     D3DCAPS9 caps;
3968     IDirect3DTexture9 *texture = NULL;
3969     IDirect3DVolumeTexture9 *volume = NULL;
3970     unsigned int x, y, z;
3971     D3DLOCKED_RECT lr;
3972     D3DLOCKED_BOX lb;
3973     DWORD color;
3974     UINT w, h;
3975     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
3976     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3977                            0.0, 1.0, 0.0, 0.0,
3978                            0.0, 0.0, 1.0, 0.0,
3979                            0.0, 0.0, 0.0, 1.0};
3980     static const D3DVERTEXELEMENT9 decl_elements[] = {
3981         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3982         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3983         D3DDECL_END()
3984     };
3985     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3986         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3987         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3988         D3DDECL_END()
3989     };
3990     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3991         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3992         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3993         D3DDECL_END()
3994     };
3995     static const D3DVERTEXELEMENT9 decl_elements4[] = {
3996         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3997         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3998         D3DDECL_END()
3999     };
4000     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
4001                                                  0x00, 0xff, 0x00, 0x00,
4002                                                  0x00, 0x00, 0x00, 0x00,
4003                                                  0x00, 0x00, 0x00, 0x00};
4004
4005     memset(&lr, 0, sizeof(lr));
4006     memset(&lb, 0, sizeof(lb));
4007     IDirect3DDevice9_GetDirect3D(device, &d3d);
4008     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
4009                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
4010         fmt = D3DFMT_A16B16G16R16;
4011     }
4012     IDirect3D9_Release(d3d);
4013
4014     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4015     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4016     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4017     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4018     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
4019     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4020     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
4021     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4022     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
4023     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
4024     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
4025     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
4026     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
4027     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
4028     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4029     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
4030     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
4031     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
4032     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
4033     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
4034     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
4035     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
4036     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4037     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
4038     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4039     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4040
4041     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4042     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
4043     w = min(1024, caps.MaxTextureWidth);
4044     h = min(1024, caps.MaxTextureHeight);
4045     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
4046                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
4047     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4048     if(!texture) {
4049         skip("Failed to create the test texture\n");
4050         return;
4051     }
4052
4053     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
4054      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
4055      * 1.0 in red and green for the x and y coords
4056      */
4057     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4058     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
4059     for(y = 0; y < h; y++) {
4060         for(x = 0; x < w; x++) {
4061             double r_f = (double) y / (double) h;
4062             double g_f = (double) x / (double) w;
4063             if(fmt == D3DFMT_A16B16G16R16) {
4064                 unsigned short r, g;
4065                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
4066                 r = (unsigned short) (r_f * 65536.0);
4067                 g = (unsigned short) (g_f * 65536.0);
4068                 dst[0] = r;
4069                 dst[1] = g;
4070                 dst[2] = 0;
4071                 dst[3] = 65535;
4072             } else {
4073                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
4074                 unsigned char r = (unsigned char) (r_f * 255.0);
4075                 unsigned char g = (unsigned char) (g_f * 255.0);
4076                 dst[0] = 0;
4077                 dst[1] = g;
4078                 dst[2] = r;
4079                 dst[3] = 255;
4080             }
4081         }
4082     }
4083     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4084     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4085     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4086     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4087
4088     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4089     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4090     hr = IDirect3DDevice9_BeginScene(device);
4091     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4092     if(SUCCEEDED(hr))
4093     {
4094         float quad1[] = {
4095             -1.0,      -1.0,       0.1,     1.0,    1.0,
4096             -1.0,       0.0,       0.1,     1.0,    1.0,
4097              0.0,      -1.0,       0.1,     1.0,    1.0,
4098              0.0,       0.0,       0.1,     1.0,    1.0,
4099         };
4100         float quad2[] = {
4101             -1.0,       0.0,       0.1,     1.0,    1.0,
4102             -1.0,       1.0,       0.1,     1.0,    1.0,
4103              0.0,       0.0,       0.1,     1.0,    1.0,
4104              0.0,       1.0,       0.1,     1.0,    1.0,
4105         };
4106         float quad3[] = {
4107              0.0,       0.0,       0.1,     0.5,    0.5,
4108              0.0,       1.0,       0.1,     0.5,    0.5,
4109              1.0,       0.0,       0.1,     0.5,    0.5,
4110              1.0,       1.0,       0.1,     0.5,    0.5,
4111         };
4112         float quad4[] = {
4113              320,       480,       0.1,     1.0,    0.0,    1.0,
4114              320,       240,       0.1,     1.0,    0.0,    1.0,
4115              640,       480,       0.1,     1.0,    0.0,    1.0,
4116              640,       240,       0.1,     1.0,    0.0,    1.0,
4117         };
4118         float mat[16] = {0.0, 0.0, 0.0, 0.0,
4119                           0.0, 0.0, 0.0, 0.0,
4120                           0.0, 0.0, 0.0, 0.0,
4121                           0.0, 0.0, 0.0, 0.0};
4122
4123         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4124         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4125         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4126         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4127         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4128
4129         /* What happens with transforms enabled? */
4130         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4131         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4132         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4133         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4134
4135         /* What happens if 4 coords are used, but only 2 given ?*/
4136         mat[8] = 1.0;
4137         mat[13] = 1.0;
4138         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4139         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4140         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4141         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4142         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4143         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4144
4145         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4146          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4147          * due to the coords in the vertices. (turns out red, indeed)
4148          */
4149         memset(mat, 0, sizeof(mat));
4150         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4151         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4152         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4153         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4154         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4155         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4156         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4157         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4158
4159         hr = IDirect3DDevice9_EndScene(device);
4160         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4161     }
4162     color = getPixelColor(device, 160, 360);
4163     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
4164     color = getPixelColor(device, 160, 120);
4165     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4166     color = getPixelColor(device, 480, 120);
4167     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
4168     color = getPixelColor(device, 480, 360);
4169     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
4170     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4171     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4172
4173     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4174     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4175
4176     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4177     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4178     hr = IDirect3DDevice9_BeginScene(device);
4179     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4180     if(SUCCEEDED(hr))
4181     {
4182         float quad1[] = {
4183             -1.0,      -1.0,       0.1,     0.8,    0.2,
4184             -1.0,       0.0,       0.1,     0.8,    0.2,
4185              0.0,      -1.0,       0.1,     0.8,    0.2,
4186              0.0,       0.0,       0.1,     0.8,    0.2,
4187         };
4188         float quad2[] = {
4189             -1.0,       0.0,       0.1,     0.5,    1.0,
4190             -1.0,       1.0,       0.1,     0.5,    1.0,
4191              0.0,       0.0,       0.1,     0.5,    1.0,
4192              0.0,       1.0,       0.1,     0.5,    1.0,
4193         };
4194         float quad3[] = {
4195              0.0,       0.0,       0.1,     0.5,    1.0,
4196              0.0,       1.0,       0.1,     0.5,    1.0,
4197              1.0,       0.0,       0.1,     0.5,    1.0,
4198              1.0,       1.0,       0.1,     0.5,    1.0,
4199         };
4200         float quad4[] = {
4201              0.0,      -1.0,       0.1,     0.8,    0.2,
4202              0.0,       0.0,       0.1,     0.8,    0.2,
4203              1.0,      -1.0,       0.1,     0.8,    0.2,
4204              1.0,       0.0,       0.1,     0.8,    0.2,
4205         };
4206         float mat[16] = {0.0, 0.0, 0.0, 0.0,
4207                           0.0, 0.0, 0.0, 0.0,
4208                           0.0, 1.0, 0.0, 0.0,
4209                           0.0, 0.0, 0.0, 0.0};
4210
4211         /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
4212         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4213         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4214         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4215         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4216
4217         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4218         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4219
4220         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
4221          * it behaves like COUNT2 because normal textures require 2 coords. */
4222         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4223         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4224         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
4225         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4226
4227         /* Just to be sure, the same as quad2 above */
4228         memset(mat, 0, sizeof(mat));
4229         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4230         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4231         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4232         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4233         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4234         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4235
4236         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
4237          * used? And what happens to the first? */
4238         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4239         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4240         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4241         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4242
4243         hr = IDirect3DDevice9_EndScene(device);
4244         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4245     }
4246     color = getPixelColor(device, 160, 360);
4247     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
4248     color = getPixelColor(device, 160, 120);
4249     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4250     color = getPixelColor(device, 480, 120);
4251     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
4252        "quad 3 has color %08x, expected 0x00ff8000\n", color);
4253     color = getPixelColor(device, 480, 360);
4254     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
4255        "quad 4 has color %08x, expected 0x0033cc00\n", color);
4256     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4257     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4258
4259     IDirect3DTexture9_Release(texture);
4260
4261     /* Test projected textures, without any fancy matrices */
4262     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
4263     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4264     if (SUCCEEDED(hr))
4265     {
4266         struct projected_textures_test_run projected_tests_1[4] =
4267         {
4268             {
4269                 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
4270                 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
4271                 decl3,
4272                 FALSE, TRUE,
4273                 {120, 300, 240, 390},
4274             },
4275             {
4276                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
4277                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4278                 decl3,
4279                 FALSE, TRUE,
4280                 {400, 360, 480, 420},
4281             },
4282             /* Try with some invalid values */
4283             {
4284                 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
4285                 0xffffffff,
4286                 decl3,
4287                 FALSE, TRUE,
4288                 {120, 60, 240, 150}
4289             },
4290             {
4291                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
4292                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4293                 decl4,
4294                 FALSE, TRUE,
4295                 {340, 210, 360, 225},
4296             }
4297         };
4298         struct projected_textures_test_run projected_tests_2[4] =
4299         {
4300             {
4301                 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
4302                 D3DTTFF_PROJECTED,
4303                 decl3,
4304                 FALSE, TRUE,
4305                 {120, 300, 240, 390},
4306             },
4307             {
4308                 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
4309                 D3DTTFF_PROJECTED,
4310                 decl,
4311                 FALSE, TRUE,
4312                 {400, 360, 480, 420},
4313             },
4314             {
4315                 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
4316                 0xffffffff,
4317                 decl,
4318                 FALSE, TRUE,
4319                 {80, 120, 160, 180},
4320             },
4321             {
4322                 "D3DTTFF_COUNT1 (draws non-projected) - top right",
4323                 D3DTTFF_COUNT1,
4324                 decl4,
4325                 FALSE, TRUE,
4326                 {340, 210, 360, 225},
4327             }
4328         };
4329         struct projected_textures_test_run projected_tests_3[4] =
4330         {
4331             {
4332                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
4333                 D3DTTFF_PROJECTED,
4334                 decl3,
4335                 TRUE, FALSE,
4336                 {120, 300, 240, 390},
4337             },
4338             {
4339                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
4340                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4341                 decl3,
4342                 TRUE, TRUE,
4343                 {440, 300, 560, 390},
4344             },
4345             {
4346                 "0xffffffff (like COUNT4 | PROJECTED) - top left",
4347                 0xffffffff,
4348                 decl3,
4349                 TRUE, TRUE,
4350                 {120, 60, 240, 150},
4351             },
4352             {
4353                 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
4354                 D3DTTFF_PROJECTED,
4355                 decl3,
4356                 FALSE, FALSE,
4357                 {440, 60, 560, 150},
4358             },
4359         };
4360
4361         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4362         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4363
4364         hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4365         ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4366         for(x = 0; x < 4; x++) {
4367             memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
4368         }
4369         hr = IDirect3DTexture9_UnlockRect(texture, 0);
4370         ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4371         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4372         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4373
4374         projected_textures_test(device, projected_tests_1);
4375         projected_textures_test(device, projected_tests_2);
4376         projected_textures_test(device, projected_tests_3);
4377
4378         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4379         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4380         IDirect3DTexture9_Release(texture);
4381     }
4382
4383     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
4384     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4385     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
4386      * Thus watch out if sampling from texels between 0 and 1.
4387      */
4388     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
4389     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
4390        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
4391     if(!volume) {
4392         skip("Failed to create a volume texture\n");
4393         goto out;
4394     }
4395
4396     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
4397     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
4398     for(z = 0; z < 32; z++) {
4399         for(y = 0; y < 32; y++) {
4400             for(x = 0; x < 32; x++) {
4401                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
4402                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
4403                 float r_f = (float) x / 31.0;
4404                 float g_f = (float) y / 31.0;
4405                 float b_f = (float) z / 31.0;
4406
4407                 if(fmt == D3DFMT_A16B16G16R16) {
4408                     unsigned short *mem_s = mem;
4409                     mem_s[0]  = r_f * 65535.0;
4410                     mem_s[1]  = g_f * 65535.0;
4411                     mem_s[2]  = b_f * 65535.0;
4412                     mem_s[3]  = 65535;
4413                 } else {
4414                     unsigned char *mem_c = mem;
4415                     mem_c[0]  = b_f * 255.0;
4416                     mem_c[1]  = g_f * 255.0;
4417                     mem_c[2]  = r_f * 255.0;
4418                     mem_c[3]  = 255;
4419                 }
4420             }
4421         }
4422     }
4423     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
4424     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4425
4426     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
4427     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4428
4429     hr = IDirect3DDevice9_BeginScene(device);
4430     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4431     if(SUCCEEDED(hr))
4432     {
4433         float quad1[] = {
4434             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4435             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4436              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4437              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4438         };
4439         float quad2[] = {
4440             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4441             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
4442              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4443              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
4444         };
4445         float quad3[] = {
4446              0.0,       0.0,       0.1,     0.0,    0.0,
4447              0.0,       1.0,       0.1,     0.0,    0.0,
4448              1.0,       0.0,       0.1,     0.0,    0.0,
4449              1.0,       1.0,       0.1,     0.0,    0.0
4450         };
4451         float quad4[] = {
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              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4455              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
4456         };
4457         float mat[16] = {1.0, 0.0, 0.0, 0.0,
4458                          0.0, 0.0, 1.0, 0.0,
4459                          0.0, 1.0, 0.0, 0.0,
4460                          0.0, 0.0, 0.0, 1.0};
4461         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4462         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4463
4464         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
4465          * values
4466          */
4467         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4468         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4469         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4470         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4471         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4472         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4473
4474         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
4475          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
4476          * otherwise the w will be missing(blue).
4477          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
4478          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
4479         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4480         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4481         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4482         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4483
4484         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
4485         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4486         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4487         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4488         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4489         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4490         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4491         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4492         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4493
4494         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4495          * disable. ATI extends it up to the amount of values needed for the volume texture
4496          */
4497         memset(mat, 0, sizeof(mat));
4498         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4499         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4500         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4501         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4502         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4503         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4504         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * 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
4511     color = getPixelColor(device, 160, 360);
4512     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4513     color = getPixelColor(device, 160, 120);
4514     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4515        "quad 2 has color %08x, expected 0x00ffff00\n", color);
4516     color = getPixelColor(device, 480, 120);
4517     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4518     color = getPixelColor(device, 480, 360);
4519     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4520
4521     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4522     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4523
4524     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4525     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4526     hr = IDirect3DDevice9_BeginScene(device);
4527     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4528     if(SUCCEEDED(hr))
4529     {
4530         float quad1[] = {
4531             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4532             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4533              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4534              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4535         };
4536         float quad2[] = {
4537             -1.0,       0.0,       0.1,
4538             -1.0,       1.0,       0.1,
4539              0.0,       0.0,       0.1,
4540              0.0,       1.0,       0.1,
4541         };
4542         float quad3[] = {
4543              0.0,       0.0,       0.1,     1.0,
4544              0.0,       1.0,       0.1,     1.0,
4545              1.0,       0.0,       0.1,     1.0,
4546              1.0,       1.0,       0.1,     1.0
4547         };
4548         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4549                            0.0, 0.0, 0.0, 0.0,
4550                            0.0, 0.0, 0.0, 0.0,
4551                            0.0, 1.0, 0.0, 0.0};
4552         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4553                            1.0, 0.0, 0.0, 0.0,
4554                            0.0, 1.0, 0.0, 0.0,
4555                            0.0, 0.0, 1.0, 0.0};
4556         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4557         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4558
4559         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4560          * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4561          * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4562          * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4563          * 4th *input* coordinate.
4564          */
4565         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4566         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4567         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4568         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4569         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4570         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4571
4572         /* None passed */
4573         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4574         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4575         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4576         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4577         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4578         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4579
4580         /* 4 used, 1 passed */
4581         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4582         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4583         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4584         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4585         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4586         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4587
4588         hr = IDirect3DDevice9_EndScene(device);
4589         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4590     }
4591     color = getPixelColor(device, 160, 360);
4592     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4593     color = getPixelColor(device, 160, 120);
4594     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4595     color = getPixelColor(device, 480, 120);
4596     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4597     /* Quad4: unused */
4598
4599     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4600     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4601
4602     IDirect3DVolumeTexture9_Release(volume);
4603
4604     out:
4605     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4606     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4607     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4608     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4609     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4610     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4611     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4612     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4613     IDirect3DVertexDeclaration9_Release(decl);
4614     IDirect3DVertexDeclaration9_Release(decl2);
4615     IDirect3DVertexDeclaration9_Release(decl3);
4616     IDirect3DVertexDeclaration9_Release(decl4);
4617 }
4618
4619 static void texdepth_test(IDirect3DDevice9 *device)
4620 {
4621     IDirect3DPixelShader9 *shader;
4622     HRESULT hr;
4623     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4624     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4625     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4626     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4627     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4628     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4629     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4630     DWORD shader_code[] = {
4631         0xffff0104,                                                                 /* ps_1_4               */
4632         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4633         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4634         0x0000fffd,                                                                 /* phase                */
4635         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4636         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4637         0x0000ffff                                                                  /* end                  */
4638     };
4639     DWORD color;
4640     float vertex[] = {
4641        -1.0,   -1.0,    0.0,
4642         1.0,   -1.0,    1.0,
4643        -1.0,    1.0,    0.0,
4644         1.0,    1.0,    1.0
4645     };
4646
4647     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4648     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4649
4650     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4651     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4652     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4653     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4654     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4655     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4656     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4657     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4658     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4659     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4660
4661     /* Fill the depth buffer with a gradient */
4662     hr = IDirect3DDevice9_BeginScene(device);
4663     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4664     if(SUCCEEDED(hr))
4665     {
4666         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4667         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4668         hr = IDirect3DDevice9_EndScene(device);
4669         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4670     }
4671
4672     /* Now perform the actual tests. Same geometry, but with the shader */
4673     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4674     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4675     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4676     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4677     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4678     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4679
4680     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4681     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4682     hr = IDirect3DDevice9_BeginScene(device);
4683     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4684     if(SUCCEEDED(hr))
4685     {
4686         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4687         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4688
4689         hr = IDirect3DDevice9_EndScene(device);
4690         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4691     }
4692
4693     color = getPixelColor(device, 158, 240);
4694     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4695     color = getPixelColor(device, 162, 240);
4696     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4697
4698     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4699     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4700
4701     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4702     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4703
4704     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4705     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4706     hr = IDirect3DDevice9_BeginScene(device);
4707     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4708     if(SUCCEEDED(hr))
4709     {
4710         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4711         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4712
4713         hr = IDirect3DDevice9_EndScene(device);
4714         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4715     }
4716
4717     color = getPixelColor(device, 318, 240);
4718     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4719     color = getPixelColor(device, 322, 240);
4720     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4721
4722     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4723     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4724
4725     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4726     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4727
4728     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4729     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4730     hr = IDirect3DDevice9_BeginScene(device);
4731     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4732     if(SUCCEEDED(hr))
4733     {
4734         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4735         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4736
4737         hr = IDirect3DDevice9_EndScene(device);
4738         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4739     }
4740
4741     color = getPixelColor(device, 1, 240);
4742     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4743
4744     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4745     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4746
4747     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4748     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4749
4750     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4751     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4752     hr = IDirect3DDevice9_BeginScene(device);
4753     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4754     if(SUCCEEDED(hr))
4755     {
4756         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4757         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4758
4759         hr = IDirect3DDevice9_EndScene(device);
4760         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4761     }
4762     color = getPixelColor(device, 318, 240);
4763     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4764     color = getPixelColor(device, 322, 240);
4765     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4766
4767     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4768     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4769
4770     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4771     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4772
4773     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4774     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4775     hr = IDirect3DDevice9_BeginScene(device);
4776     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4777     if(SUCCEEDED(hr))
4778     {
4779         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4780         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4781
4782         hr = IDirect3DDevice9_EndScene(device);
4783         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4784     }
4785
4786     color = getPixelColor(device, 1, 240);
4787     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4788
4789     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4790     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4791
4792     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4793     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4794
4795     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4796     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4797     hr = IDirect3DDevice9_BeginScene(device);
4798     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4799     if(SUCCEEDED(hr))
4800     {
4801         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4802         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4803
4804         hr = IDirect3DDevice9_EndScene(device);
4805         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4806     }
4807
4808     color = getPixelColor(device, 638, 240);
4809     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4810
4811     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4812     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4813
4814     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4815     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4816
4817     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4818     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4819     hr = IDirect3DDevice9_BeginScene(device);
4820     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4821     if(SUCCEEDED(hr))
4822     {
4823         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4824         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4825
4826         hr = IDirect3DDevice9_EndScene(device);
4827         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4828     }
4829
4830     color = getPixelColor(device, 638, 240);
4831     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4832
4833     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4834     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4835
4836     /* Cleanup */
4837     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4838     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4839     IDirect3DPixelShader9_Release(shader);
4840
4841     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4842     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4843     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4844     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4845 }
4846
4847 static void texkill_test(IDirect3DDevice9 *device)
4848 {
4849     IDirect3DPixelShader9 *shader;
4850     HRESULT hr;
4851     DWORD color;
4852
4853     const float vertex[] = {
4854     /*                          bottom  top    right    left */
4855         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4856          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4857         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4858          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4859     };
4860
4861     DWORD shader_code_11[] = {
4862     0xffff0101,                                                             /* ps_1_1                     */
4863     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4864     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4865     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4866     0x0000ffff                                                              /* end                        */
4867     };
4868     DWORD shader_code_20[] = {
4869     0xffff0200,                                                             /* ps_2_0                     */
4870     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4871     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4872     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4873     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4874     0x0000ffff                                                              /* end                        */
4875     };
4876
4877     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4878     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4879     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4880     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4881
4882     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4883     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4884     hr = IDirect3DDevice9_BeginScene(device);
4885     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4886     if(SUCCEEDED(hr))
4887     {
4888         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4889         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4890         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4891         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4892         hr = IDirect3DDevice9_EndScene(device);
4893         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4894     }
4895     color = getPixelColor(device, 63, 46);
4896     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4897     color = getPixelColor(device, 66, 46);
4898     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4899     color = getPixelColor(device, 63, 49);
4900     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4901     color = getPixelColor(device, 66, 49);
4902     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4903
4904     color = getPixelColor(device, 578, 46);
4905     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4906     color = getPixelColor(device, 575, 46);
4907     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4908     color = getPixelColor(device, 578, 49);
4909     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4910     color = getPixelColor(device, 575, 49);
4911     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4912
4913     color = getPixelColor(device, 63, 430);
4914     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4915     color = getPixelColor(device, 63, 433);
4916     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4917     color = getPixelColor(device, 66, 433);
4918     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4919     color = getPixelColor(device, 66, 430);
4920     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4921
4922     color = getPixelColor(device, 578, 430);
4923     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4924     color = getPixelColor(device, 578, 433);
4925     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4926     color = getPixelColor(device, 575, 433);
4927     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4928     color = getPixelColor(device, 575, 430);
4929     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4930
4931     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4932     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4933
4934     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4935     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4936     IDirect3DPixelShader9_Release(shader);
4937
4938     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4939     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4940     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4941     if(FAILED(hr)) {
4942         skip("Failed to create 2.0 test shader, most likely not supported\n");
4943         return;
4944     }
4945
4946     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4947     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4948     hr = IDirect3DDevice9_BeginScene(device);
4949     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4950     if(SUCCEEDED(hr))
4951     {
4952         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4953         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4954         hr = IDirect3DDevice9_EndScene(device);
4955         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4956     }
4957
4958     color = getPixelColor(device, 63, 46);
4959     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4960     color = getPixelColor(device, 66, 46);
4961     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4962     color = getPixelColor(device, 63, 49);
4963     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4964     color = getPixelColor(device, 66, 49);
4965     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4966
4967     color = getPixelColor(device, 578, 46);
4968     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4969     color = getPixelColor(device, 575, 46);
4970     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4971     color = getPixelColor(device, 578, 49);
4972     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4973     color = getPixelColor(device, 575, 49);
4974     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4975
4976     color = getPixelColor(device, 63, 430);
4977     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4978     color = getPixelColor(device, 63, 433);
4979     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4980     color = getPixelColor(device, 66, 433);
4981     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4982     color = getPixelColor(device, 66, 430);
4983     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4984
4985     color = getPixelColor(device, 578, 430);
4986     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4987     color = getPixelColor(device, 578, 433);
4988     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4989     color = getPixelColor(device, 575, 433);
4990     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4991     color = getPixelColor(device, 575, 430);
4992     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4993
4994     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4995     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4996
4997     /* Cleanup */
4998     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4999     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
5000     IDirect3DPixelShader9_Release(shader);
5001 }
5002
5003 static void x8l8v8u8_test(IDirect3DDevice9 *device)
5004 {
5005     IDirect3D9 *d3d9;
5006     HRESULT hr;
5007     IDirect3DTexture9 *texture;
5008     IDirect3DPixelShader9 *shader;
5009     IDirect3DPixelShader9 *shader2;
5010     D3DLOCKED_RECT lr;
5011     DWORD color;
5012     DWORD shader_code[] = {
5013         0xffff0101,                             /* ps_1_1       */
5014         0x00000042, 0xb00f0000,                 /* tex t0       */
5015         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
5016         0x0000ffff                              /* end          */
5017     };
5018     DWORD shader_code2[] = {
5019         0xffff0101,                             /* ps_1_1       */
5020         0x00000042, 0xb00f0000,                 /* tex t0       */
5021         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
5022         0x0000ffff                              /* end          */
5023     };
5024
5025     float quad[] = {
5026        -1.0,   -1.0,   0.1,     0.5,    0.5,
5027         1.0,   -1.0,   0.1,     0.5,    0.5,
5028        -1.0,    1.0,   0.1,     0.5,    0.5,
5029         1.0,    1.0,   0.1,     0.5,    0.5,
5030     };
5031
5032     memset(&lr, 0, sizeof(lr));
5033     IDirect3DDevice9_GetDirect3D(device, &d3d9);
5034     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5035                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
5036     IDirect3D9_Release(d3d9);
5037     if(FAILED(hr)) {
5038         skip("No D3DFMT_X8L8V8U8 support\n");
5039         return;
5040     };
5041
5042     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5043     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5044
5045     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
5046     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
5047     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5048     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
5049     *((DWORD *) lr.pBits) = 0x11ca3141;
5050     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5051     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
5052
5053     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5054     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5055     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
5056     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5057
5058     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5059     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5060     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5061     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5062     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5063     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5064
5065     hr = IDirect3DDevice9_BeginScene(device);
5066     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5067     if(SUCCEEDED(hr))
5068     {
5069         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5070         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5071
5072         hr = IDirect3DDevice9_EndScene(device);
5073         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5074     }
5075     color = getPixelColor(device, 578, 430);
5076     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
5077        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
5078     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5079     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5080
5081     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
5082     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5083     hr = IDirect3DDevice9_BeginScene(device);
5084     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5085     if(SUCCEEDED(hr))
5086     {
5087         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5088         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5089
5090         hr = IDirect3DDevice9_EndScene(device);
5091         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5092     }
5093     color = getPixelColor(device, 578, 430);
5094     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
5095     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5096     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5097
5098     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5099     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5100     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5101     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5102     IDirect3DPixelShader9_Release(shader);
5103     IDirect3DPixelShader9_Release(shader2);
5104     IDirect3DTexture9_Release(texture);
5105 }
5106
5107 static void autogen_mipmap_test(IDirect3DDevice9 *device)
5108 {
5109     HRESULT hr;
5110     IDirect3D9 *d3d;
5111     IDirect3DTexture9 *texture = NULL;
5112     IDirect3DSurface9 *surface;
5113     DWORD color;
5114     const RECT r1 = {256, 256, 512, 512};
5115     const RECT r2 = {512, 256, 768, 512};
5116     const RECT r3 = {256, 512, 512, 768};
5117     const RECT r4 = {512, 512, 768, 768};
5118     unsigned int x, y;
5119     D3DLOCKED_RECT lr;
5120     memset(&lr, 0, sizeof(lr));
5121
5122     IDirect3DDevice9_GetDirect3D(device, &d3d);
5123     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5124        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
5125         skip("No autogenmipmap support\n");
5126         IDirect3D9_Release(d3d);
5127         return;
5128     }
5129     IDirect3D9_Release(d3d);
5130
5131     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5132     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5133
5134     /* Make the mipmap big, so that a smaller mipmap is used
5135      */
5136     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5137                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5138     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5139
5140     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5141     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5142     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5143     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5144     for(y = 0; y < 1024; y++) {
5145         for(x = 0; x < 1024; x++) {
5146             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5147             POINT pt;
5148
5149             pt.x = x;
5150             pt.y = y;
5151             if(PtInRect(&r1, pt)) {
5152                 *dst = 0xffff0000;
5153             } else if(PtInRect(&r2, pt)) {
5154                 *dst = 0xff00ff00;
5155             } else if(PtInRect(&r3, pt)) {
5156                 *dst = 0xff0000ff;
5157             } else if(PtInRect(&r4, pt)) {
5158                 *dst = 0xff000000;
5159             } else {
5160                 *dst = 0xffffffff;
5161             }
5162         }
5163     }
5164     hr = IDirect3DSurface9_UnlockRect(surface);
5165     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5166     IDirect3DSurface9_Release(surface);
5167
5168     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5169     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5170     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5171     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5172
5173     hr = IDirect3DDevice9_BeginScene(device);
5174     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5175     if(SUCCEEDED(hr)) {
5176         const float quad[] =  {
5177            -0.5,   -0.5,    0.1,    0.0,    0.0,
5178            -0.5,    0.5,    0.1,    0.0,    1.0,
5179             0.5,   -0.5,    0.1,    1.0,    0.0,
5180             0.5,    0.5,    0.1,    1.0,    1.0
5181         };
5182
5183         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5184         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5185         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5186         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5187         hr = IDirect3DDevice9_EndScene(device);
5188         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5189     }
5190     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5191     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5192     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
5193     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5194     IDirect3DTexture9_Release(texture);
5195
5196     color = getPixelColor(device, 200, 200);
5197     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5198     color = getPixelColor(device, 280, 200);
5199     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5200     color = getPixelColor(device, 360, 200);
5201     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5202     color = getPixelColor(device, 440, 200);
5203     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5204     color = getPixelColor(device, 200, 270);
5205     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5206     color = getPixelColor(device, 280, 270);
5207     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5208     color = getPixelColor(device, 360, 270);
5209     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5210     color = getPixelColor(device, 440, 270);
5211     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5212     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5213     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5214 }
5215
5216 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
5217 {
5218     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5219     IDirect3DVertexDeclaration9 *decl;
5220     HRESULT hr;
5221     DWORD color;
5222     DWORD shader_code_11[] =  {
5223         0xfffe0101,                                         /* vs_1_1           */
5224         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5225         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5226         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5227         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5228         0x0000ffff                                          /* end              */
5229     };
5230     DWORD shader_code_11_2[] =  {
5231         0xfffe0101,                                         /* vs_1_1           */
5232         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
5233         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
5234         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5235         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5236         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5237         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5238         0x0000ffff                                          /* end              */
5239     };
5240     DWORD shader_code_20[] =  {
5241         0xfffe0200,                                         /* vs_2_0           */
5242         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5243         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5244         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5245         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5246         0x0000ffff                                          /* end              */
5247     };
5248     DWORD shader_code_20_2[] =  {
5249         0xfffe0200,                                         /* vs_2_0           */
5250         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
5251         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
5252         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5253         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5254         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5255         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5256         0x0000ffff                                          /* end              */
5257     };
5258     static const D3DVERTEXELEMENT9 decl_elements[] = {
5259         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5260         D3DDECL_END()
5261     };
5262     float quad1[] = {
5263         -1.0,   -1.0,   0.1,
5264          0.0,   -1.0,   0.1,
5265         -1.0,    0.0,   0.1,
5266          0.0,    0.0,   0.1
5267     };
5268     float quad2[] = {
5269          0.0,   -1.0,   0.1,
5270          1.0,   -1.0,   0.1,
5271          0.0,    0.0,   0.1,
5272          1.0,    0.0,   0.1
5273     };
5274     float quad3[] = {
5275          0.0,    0.0,   0.1,
5276          1.0,    0.0,   0.1,
5277          0.0,    1.0,   0.1,
5278          1.0,    1.0,   0.1
5279     };
5280     float quad4[] = {
5281         -1.0,    0.0,   0.1,
5282          0.0,    0.0,   0.1,
5283         -1.0,    1.0,   0.1,
5284          0.0,    1.0,   0.1
5285     };
5286     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
5287     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
5288
5289     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5290     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5291
5292     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
5293     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5294     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
5295     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5296     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
5297     if(FAILED(hr)) shader_20 = NULL;
5298     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
5299     if(FAILED(hr)) shader_20_2 = NULL;
5300     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5301     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5302
5303     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
5304     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5305     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
5306     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5307     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5308     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5309
5310     hr = IDirect3DDevice9_BeginScene(device);
5311     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5312     if(SUCCEEDED(hr))
5313     {
5314         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
5315         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5316         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5317         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5318
5319         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
5320         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5321         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5322         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5323
5324         if(shader_20) {
5325             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
5326             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5327             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5328             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5329         }
5330
5331         if(shader_20_2) {
5332             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
5333             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5334             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5335             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5336         }
5337
5338         hr = IDirect3DDevice9_EndScene(device);
5339         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5340     }
5341
5342     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5343     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5344     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5345     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5346
5347     color = getPixelColor(device, 160, 360);
5348     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5349        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
5350     color = getPixelColor(device, 480, 360);
5351     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5352        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
5353     if(shader_20) {
5354         color = getPixelColor(device, 480, 120);
5355         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5356            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
5357     }
5358     if(shader_20_2) {
5359         color = getPixelColor(device, 160, 120);
5360         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5361            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5362     }
5363     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5364     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5365
5366     IDirect3DVertexDeclaration9_Release(decl);
5367     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
5368     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
5369     IDirect3DVertexShader9_Release(shader_11_2);
5370     IDirect3DVertexShader9_Release(shader_11);
5371 }
5372
5373 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
5374 {
5375     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
5376     HRESULT hr;
5377     DWORD color;
5378     DWORD shader_code_11[] =  {
5379         0xffff0101,                                         /* ps_1_1           */
5380         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5381         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5382         0x0000ffff                                          /* end              */
5383     };
5384     DWORD shader_code_12[] =  {
5385         0xffff0102,                                         /* ps_1_2           */
5386         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5387         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5388         0x0000ffff                                          /* end              */
5389     };
5390     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
5391      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
5392      * During development of this test, 1.3 shaders were verified too
5393      */
5394     DWORD shader_code_14[] =  {
5395         0xffff0104,                                         /* ps_1_4           */
5396         /* Try to make one constant local. It gets clamped too, although the binary contains
5397          * the bigger numbers
5398          */
5399         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
5400         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5401         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5402         0x0000ffff                                          /* end              */
5403     };
5404     DWORD shader_code_20[] =  {
5405         0xffff0200,                                         /* ps_2_0           */
5406         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5407         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5408         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
5409         0x0000ffff                                          /* end              */
5410     };
5411     float quad1[] = {
5412         -1.0,   -1.0,   0.1,
5413          0.0,   -1.0,   0.1,
5414         -1.0,    0.0,   0.1,
5415          0.0,    0.0,   0.1
5416     };
5417     float quad2[] = {
5418          0.0,   -1.0,   0.1,
5419          1.0,   -1.0,   0.1,
5420          0.0,    0.0,   0.1,
5421          1.0,    0.0,   0.1
5422     };
5423     float quad3[] = {
5424          0.0,    0.0,   0.1,
5425          1.0,    0.0,   0.1,
5426          0.0,    1.0,   0.1,
5427          1.0,    1.0,   0.1
5428     };
5429     float quad4[] = {
5430         -1.0,    0.0,   0.1,
5431          0.0,    0.0,   0.1,
5432         -1.0,    1.0,   0.1,
5433          0.0,    1.0,   0.1
5434     };
5435     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
5436     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
5437
5438     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5439     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5440
5441     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5442     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5443     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5444     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5445     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5446     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5447     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
5448     if(FAILED(hr)) shader_20 = NULL;
5449
5450     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5451     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5452     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5453     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5454     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5455     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5456
5457     hr = IDirect3DDevice9_BeginScene(device);
5458     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5459     if(SUCCEEDED(hr))
5460     {
5461         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5462         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5463         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5464         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5465
5466         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5467         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5468         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5469         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5470
5471         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5472         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5473         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5474         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5475
5476         if(shader_20) {
5477             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
5478             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5479             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5480             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5481         }
5482
5483         hr = IDirect3DDevice9_EndScene(device);
5484         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5485     }
5486     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5487     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5488
5489     color = getPixelColor(device, 160, 360);
5490     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5491        "quad 1 has color %08x, expected 0x00808000\n", color);
5492     color = getPixelColor(device, 480, 360);
5493     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5494        "quad 2 has color %08x, expected 0x00808000\n", color);
5495     color = getPixelColor(device, 480, 120);
5496     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5497        "quad 3 has color %08x, expected 0x00808000\n", color);
5498     if(shader_20) {
5499         color = getPixelColor(device, 160, 120);
5500         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5501            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5502     }
5503     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5504     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5505
5506     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5507     IDirect3DPixelShader9_Release(shader_14);
5508     IDirect3DPixelShader9_Release(shader_12);
5509     IDirect3DPixelShader9_Release(shader_11);
5510 }
5511
5512 static void dp2add_ps_test(IDirect3DDevice9 *device)
5513 {
5514     IDirect3DPixelShader9 *shader_dp2add = NULL;
5515     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5516     HRESULT hr;
5517     DWORD color;
5518
5519     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
5520      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5521      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
5522      * r0 first.
5523      * The result here for the r,g,b components should be roughly 0.5:
5524      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5525     static const DWORD shader_code_dp2add[] =  {
5526         0xffff0200,                                                             /* ps_2_0                       */
5527         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
5528
5529         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5530         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
5531
5532         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
5533         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5534         0x0000ffff                                                              /* end                          */
5535     };
5536
5537     /* Test the _sat modifier, too.  Result here should be:
5538      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5539      *      _SAT: ==> 1.0
5540      *   ADD: (1.0 + -0.5) = 0.5
5541      */
5542     static const DWORD shader_code_dp2add_sat[] =  {
5543         0xffff0200,                                                             /* ps_2_0                           */
5544         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
5545
5546         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
5547         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
5548         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5549
5550         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5551         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5552         0x0000ffff                                                              /* end                              */
5553     };
5554
5555     const float quad[] = {
5556         -1.0,   -1.0,   0.1,
5557          1.0,   -1.0,   0.1,
5558         -1.0,    1.0,   0.1,
5559          1.0,    1.0,   0.1
5560     };
5561
5562
5563     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5564     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5565
5566     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5567     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5568
5569     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5570     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5571
5572     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5573     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5574
5575     if (shader_dp2add) {
5576
5577         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5578         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5579
5580         hr = IDirect3DDevice9_BeginScene(device);
5581         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5582         if(SUCCEEDED(hr))
5583         {
5584             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5585             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5586
5587             hr = IDirect3DDevice9_EndScene(device);
5588             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5589         }
5590
5591         color = getPixelColor(device, 360, 240);
5592         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5593                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5594
5595         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5596         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5597
5598         IDirect3DPixelShader9_Release(shader_dp2add);
5599     } else {
5600         skip("dp2add shader creation failed\n");
5601     }
5602
5603     if (shader_dp2add_sat) {
5604
5605         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5606         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5607
5608         hr = IDirect3DDevice9_BeginScene(device);
5609         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5610         if(SUCCEEDED(hr))
5611         {
5612             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5613             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5614
5615             hr = IDirect3DDevice9_EndScene(device);
5616             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5617         }
5618
5619         color = getPixelColor(device, 360, 240);
5620         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5621                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5622
5623         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5624         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5625
5626         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5627     } else {
5628         skip("dp2add shader creation failed\n");
5629     }
5630
5631     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5632     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5633 }
5634
5635 static void cnd_test(IDirect3DDevice9 *device)
5636 {
5637     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5638     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5639     HRESULT hr;
5640     DWORD color;
5641     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5642      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5643      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5644      */
5645     DWORD shader_code_11[] =  {
5646         0xffff0101,                                                                 /* ps_1_1               */
5647         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5648         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5649         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5650         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5651         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5652         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5653         0x0000ffff                                                                  /* end                  */
5654     };
5655     DWORD shader_code_12[] =  {
5656         0xffff0102,                                                                 /* ps_1_2               */
5657         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5658         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5659         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5660         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5661         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5662         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5663         0x0000ffff                                                                  /* end                  */
5664     };
5665     DWORD shader_code_13[] =  {
5666         0xffff0103,                                                                 /* ps_1_3               */
5667         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5668         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5669         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5670         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5671         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5672         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5673         0x0000ffff                                                                  /* end                  */
5674     };
5675     DWORD shader_code_14[] =  {
5676         0xffff0104,                                                                 /* ps_1_3               */
5677         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5678         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5679         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5680         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5681         0x0000ffff                                                                  /* end                  */
5682     };
5683
5684     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5685      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5686      * set by the compiler, it was added manually after compilation. Note that the COISSUE
5687      * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5688      * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5689      * well enough.
5690      *
5691      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5692      * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5693      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5694      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5695      */
5696     DWORD shader_code_11_coissue[] =  {
5697         0xffff0101,                                                             /* ps_1_1                   */
5698         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5699         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5700         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5701         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5702         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5703         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5704         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5705         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5706         /* 0x40000000 = D3DSI_COISSUE */
5707         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5708         0x0000ffff                                                              /* end                      */
5709     };
5710     DWORD shader_code_12_coissue[] =  {
5711         0xffff0102,                                                             /* ps_1_2                   */
5712         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5713         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5714         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5715         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5716         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5717         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5718         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5719         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5720         /* 0x40000000 = D3DSI_COISSUE */
5721         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5722         0x0000ffff                                                              /* end                      */
5723     };
5724     DWORD shader_code_13_coissue[] =  {
5725         0xffff0103,                                                             /* ps_1_3                   */
5726         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5727         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5728         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5729         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5730         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5731         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5732         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5733         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5734         /* 0x40000000 = D3DSI_COISSUE */
5735         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5736         0x0000ffff                                                              /* end                      */
5737     };
5738     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5739      * compare against 0.5
5740      */
5741     DWORD shader_code_14_coissue[] =  {
5742         0xffff0104,                                                             /* ps_1_4                   */
5743         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5744         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5745         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5746         /* 0x40000000 = D3DSI_COISSUE */
5747         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5748         0x0000ffff                                                              /* end                      */
5749     };
5750     float quad1[] = {
5751         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5752          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5753         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5754          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5755     };
5756     float quad2[] = {
5757          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5758          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5759          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5760          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5761     };
5762     float quad3[] = {
5763          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5764          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5765          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5766          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5767     };
5768     float quad4[] = {
5769         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5770          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5771         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5772          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5773     };
5774     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5775     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5776     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5777     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5778
5779     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5780     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5781
5782     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5783     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5784     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5785     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5786     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5787     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5788     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5789     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5790     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5791     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5792     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5793     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5794     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5795     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5796     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5797     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5798
5799     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5800     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5801     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5802     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5803     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5804     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5805
5806     hr = IDirect3DDevice9_BeginScene(device);
5807     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5808     if(SUCCEEDED(hr))
5809     {
5810         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5811         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5812         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5813         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5814
5815         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5816         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5817         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5818         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5819
5820         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5821         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5822         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5823         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5824
5825         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5826         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5827         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5828         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5829
5830         hr = IDirect3DDevice9_EndScene(device);
5831         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5832     }
5833
5834     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5835     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5836
5837     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5838     color = getPixelColor(device, 158, 118);
5839     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5840     color = getPixelColor(device, 162, 118);
5841     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5842     color = getPixelColor(device, 158, 122);
5843     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5844     color = getPixelColor(device, 162, 122);
5845     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5846
5847     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5848     color = getPixelColor(device, 158, 358);
5849     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5850     color = getPixelColor(device, 162, 358);
5851     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5852         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5853     color = getPixelColor(device, 158, 362);
5854     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5855     color = getPixelColor(device, 162, 362);
5856     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5857         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5858
5859     /* 1.2 shader */
5860     color = getPixelColor(device, 478, 358);
5861     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5862     color = getPixelColor(device, 482, 358);
5863     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5864         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5865     color = getPixelColor(device, 478, 362);
5866     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5867     color = getPixelColor(device, 482, 362);
5868     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5869         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5870
5871     /* 1.3 shader */
5872     color = getPixelColor(device, 478, 118);
5873     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5874     color = getPixelColor(device, 482, 118);
5875     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5876         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5877     color = getPixelColor(device, 478, 122);
5878     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5879     color = getPixelColor(device, 482, 122);
5880     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5881         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5882
5883     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5884     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5885
5886     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5887     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5888     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5889     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5890     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5891     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5892
5893     hr = IDirect3DDevice9_BeginScene(device);
5894     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5895     if(SUCCEEDED(hr))
5896     {
5897         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5898         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5899         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5900         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5901
5902         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5903         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5904         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5905         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5906
5907         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5908         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5909         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5910         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5911
5912         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5913         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5914         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5915         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5916
5917         hr = IDirect3DDevice9_EndScene(device);
5918         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5919     }
5920
5921     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5922     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5923
5924     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5925      * that we swapped the values in c1 and c2 to make the other tests return some color
5926      */
5927     color = getPixelColor(device, 158, 118);
5928     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5929     color = getPixelColor(device, 162, 118);
5930     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5931     color = getPixelColor(device, 158, 122);
5932     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5933     color = getPixelColor(device, 162, 122);
5934     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5935
5936     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5937      * (The Win7 nvidia driver always selects c2)
5938      */
5939     color = getPixelColor(device, 158, 358);
5940     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5941         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5942     color = getPixelColor(device, 162, 358);
5943     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5944         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5945     color = getPixelColor(device, 158, 362);
5946     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5947         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5948     color = getPixelColor(device, 162, 362);
5949     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5950         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5951
5952     /* 1.2 shader */
5953     color = getPixelColor(device, 478, 358);
5954     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5955         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5956     color = getPixelColor(device, 482, 358);
5957     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5958         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5959     color = getPixelColor(device, 478, 362);
5960     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5961         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5962     color = getPixelColor(device, 482, 362);
5963     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5964         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5965
5966     /* 1.3 shader */
5967     color = getPixelColor(device, 478, 118);
5968     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5969         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5970     color = getPixelColor(device, 482, 118);
5971     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5972         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5973     color = getPixelColor(device, 478, 122);
5974     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5975         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5976     color = getPixelColor(device, 482, 122);
5977     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5978         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5979
5980     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5981     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5982
5983     IDirect3DPixelShader9_Release(shader_14_coissue);
5984     IDirect3DPixelShader9_Release(shader_13_coissue);
5985     IDirect3DPixelShader9_Release(shader_12_coissue);
5986     IDirect3DPixelShader9_Release(shader_11_coissue);
5987     IDirect3DPixelShader9_Release(shader_14);
5988     IDirect3DPixelShader9_Release(shader_13);
5989     IDirect3DPixelShader9_Release(shader_12);
5990     IDirect3DPixelShader9_Release(shader_11);
5991 }
5992
5993 static void nested_loop_test(IDirect3DDevice9 *device) {
5994     const DWORD shader_code[] = {
5995         0xffff0300,                                                             /* ps_3_0               */
5996         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5997         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5998         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5999         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
6000         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
6001         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
6002         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
6003         0x0000001d,                                                             /* endloop              */
6004         0x0000001d,                                                             /* endloop              */
6005         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
6006         0x0000ffff                                                              /* end                  */
6007     };
6008     const DWORD vshader_code[] = {
6009         0xfffe0300,                                                             /* vs_3_0               */
6010         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
6011         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
6012         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
6013         0x0000ffff                                                              /* end                  */
6014     };
6015     IDirect3DPixelShader9 *shader;
6016     IDirect3DVertexShader9 *vshader;
6017     HRESULT hr;
6018     DWORD color;
6019     const float quad[] = {
6020         -1.0,   -1.0,   0.1,
6021          1.0,   -1.0,   0.1,
6022         -1.0,    1.0,   0.1,
6023          1.0,    1.0,   0.1
6024     };
6025
6026     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
6027     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
6028     hr = IDirect3DDevice9_SetPixelShader(device, shader);
6029     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
6030     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6031     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
6032     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6033     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
6034     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6035     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6036     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
6037     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6038
6039     hr = IDirect3DDevice9_BeginScene(device);
6040     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6041     if(SUCCEEDED(hr))
6042     {
6043         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6044         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6045         hr = IDirect3DDevice9_EndScene(device);
6046         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6047     }
6048
6049     color = getPixelColor(device, 360, 240);
6050     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
6051        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
6052
6053     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6054     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6055
6056     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6057     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
6058     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6059     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
6060     IDirect3DPixelShader9_Release(shader);
6061     IDirect3DVertexShader9_Release(vshader);
6062 }
6063
6064 struct varying_test_struct
6065 {
6066     const DWORD             *shader_code;
6067     IDirect3DPixelShader9   *shader;
6068     DWORD                   color, color_rhw;
6069     const char              *name;
6070     BOOL                    todo, todo_rhw;
6071 };
6072
6073 struct hugeVertex
6074 {
6075     float pos_x,        pos_y,      pos_z,      rhw;
6076     float weight_1,     weight_2,   weight_3,   weight_4;
6077     float index_1,      index_2,    index_3,    index_4;
6078     float normal_1,     normal_2,   normal_3,   normal_4;
6079     float fog_1,        fog_2,      fog_3,      fog_4;
6080     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
6081     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
6082     float binormal_1,   binormal_2, binormal_3, binormal_4;
6083     float depth_1,      depth_2,    depth_3,    depth_4;
6084     DWORD diffuse, specular;
6085 };
6086
6087 static void pretransformed_varying_test(IDirect3DDevice9 *device) {
6088     /* dcl_position: fails to compile */
6089     const DWORD blendweight_code[] = {
6090         0xffff0300,                             /* ps_3_0                   */
6091         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
6092         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6093         0x0000ffff                              /* end                      */
6094     };
6095     const DWORD blendindices_code[] = {
6096         0xffff0300,                             /* ps_3_0                   */
6097         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
6098         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6099         0x0000ffff                              /* end                      */
6100     };
6101     const DWORD normal_code[] = {
6102         0xffff0300,                             /* ps_3_0                   */
6103         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
6104         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6105         0x0000ffff                              /* end                      */
6106     };
6107     /* psize: fails? */
6108     const DWORD texcoord0_code[] = {
6109         0xffff0300,                             /* ps_3_0                   */
6110         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
6111         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6112         0x0000ffff                              /* end                      */
6113     };
6114     const DWORD tangent_code[] = {
6115         0xffff0300,                             /* ps_3_0                   */
6116         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
6117         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6118         0x0000ffff                              /* end                      */
6119     };
6120     const DWORD binormal_code[] = {
6121         0xffff0300,                             /* ps_3_0                   */
6122         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
6123         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6124         0x0000ffff                              /* end                      */
6125     };
6126     /* tessfactor: fails */
6127     /* positiont: fails */
6128     const DWORD color_code[] = {
6129         0xffff0300,                             /* ps_3_0                   */
6130         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
6131         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6132         0x0000ffff                              /* end                      */
6133     };
6134     const DWORD fog_code[] = {
6135         0xffff0300,                             /* ps_3_0                   */
6136         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
6137         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6138         0x0000ffff                              /* end                      */
6139     };
6140     const DWORD depth_code[] = {
6141         0xffff0300,                             /* ps_3_0                   */
6142         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
6143         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6144         0x0000ffff                              /* end                      */
6145     };
6146     const DWORD specular_code[] = {
6147         0xffff0300,                             /* ps_3_0                   */
6148         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
6149         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6150         0x0000ffff                              /* end                      */
6151     };
6152     /* sample: fails */
6153
6154     struct varying_test_struct tests[] = {
6155        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
6156        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
6157        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
6158        /* Why does dx not forward the texcoord? */
6159        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
6160        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
6161        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
6162        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
6163        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
6164        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
6165        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
6166     };
6167     /* Declare a monster vertex type :-) */
6168     static const D3DVERTEXELEMENT9 decl_elements[] = {
6169         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6170         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
6171         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
6172         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
6173         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
6174         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6175         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
6176         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
6177         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
6178         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6179         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
6180         D3DDECL_END()
6181     };
6182     struct hugeVertex data[4] = {
6183         {
6184             -1.0,   -1.0,   0.1,    1.0,
6185              0.1,    0.1,   0.1,    0.1,
6186              0.2,    0.2,   0.2,    0.2,
6187              0.3,    0.3,   0.3,    0.3,
6188              0.4,    0.4,   0.4,    0.4,
6189              0.50,   0.55,  0.55,   0.55,
6190              0.6,    0.6,   0.6,    0.7,
6191              0.7,    0.7,   0.7,    0.6,
6192              0.8,    0.8,   0.8,    0.8,
6193              0xe6e6e6e6, /* 0.9 * 256 */
6194              0x224488ff  /* Nothing special */
6195         },
6196         {
6197              1.0,   -1.0,   0.1,    1.0,
6198              0.1,    0.1,   0.1,    0.1,
6199              0.2,    0.2,   0.2,    0.2,
6200              0.3,    0.3,   0.3,    0.3,
6201              0.4,    0.4,   0.4,    0.4,
6202              0.50,   0.55,  0.55,   0.55,
6203              0.6,    0.6,   0.6,    0.7,
6204              0.7,    0.7,   0.7,    0.6,
6205              0.8,    0.8,   0.8,    0.8,
6206              0xe6e6e6e6, /* 0.9 * 256 */
6207              0x224488ff /* Nothing special */
6208         },
6209         {
6210             -1.0,    1.0,   0.1,    1.0,
6211              0.1,    0.1,   0.1,    0.1,
6212              0.2,    0.2,   0.2,    0.2,
6213              0.3,    0.3,   0.3,    0.3,
6214              0.4,    0.4,   0.4,    0.4,
6215              0.50,   0.55,  0.55,   0.55,
6216              0.6,    0.6,   0.6,    0.7,
6217              0.7,    0.7,   0.7,    0.6,
6218              0.8,    0.8,   0.8,    0.8,
6219              0xe6e6e6e6, /* 0.9 * 256 */
6220              0x224488ff /* Nothing special */
6221         },
6222         {
6223              1.0,    1.0,   0.1,    1.0,
6224              0.1,    0.1,   0.1,    0.1,
6225              0.2,    0.2,   0.2,    0.2,
6226              0.3,    0.3,   0.3,    0.3,
6227              0.4,    0.4,   0.4,    0.4,
6228              0.50,   0.55,  0.55,   0.55,
6229              0.6,    0.6,   0.6,    0.7,
6230              0.7,    0.7,   0.7,    0.6,
6231              0.8,    0.8,   0.8,    0.8,
6232              0xe6e6e6e6, /* 0.9 * 256 */
6233              0x224488ff /* Nothing special */
6234         },
6235     };
6236     struct hugeVertex data2[4];
6237     IDirect3DVertexDeclaration9 *decl;
6238     HRESULT hr;
6239     unsigned int i;
6240     DWORD color, r, g, b, r_e, g_e, b_e;
6241
6242     memcpy(data2, data, sizeof(data2));
6243     data2[0].pos_x = 0;     data2[0].pos_y = 0;
6244     data2[1].pos_x = 640;   data2[1].pos_y = 0;
6245     data2[2].pos_x = 0;     data2[2].pos_y = 480;
6246     data2[3].pos_x = 640;   data2[3].pos_y = 480;
6247
6248     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6249     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6250     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6251     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6252
6253     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6254     {
6255         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
6256         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
6257            tests[i].name, hr);
6258     }
6259
6260     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6261     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6262     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6263     {
6264         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6265         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6266
6267         hr = IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
6268         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6269
6270         hr = IDirect3DDevice9_BeginScene(device);
6271         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6272         if(SUCCEEDED(hr))
6273         {
6274             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
6275             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6276             hr = IDirect3DDevice9_EndScene(device);
6277             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6278         }
6279
6280         color = getPixelColor(device, 360, 240);
6281         r = color & 0x00ff0000 >> 16;
6282         g = color & 0x0000ff00 >>  8;
6283         b = color & 0x000000ff;
6284         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
6285         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
6286         b_e = tests[i].color_rhw & 0x000000ff;
6287
6288         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6289         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6290
6291         if(tests[i].todo_rhw) {
6292             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
6293              * pipeline
6294              */
6295             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6296                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
6297                          tests[i].name, color, tests[i].color_rhw);
6298         } else {
6299             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6300                "Test %s returned color 0x%08x, expected 0x%08x\n",
6301                tests[i].name, color, tests[i].color_rhw);
6302         }
6303     }
6304
6305     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6306     {
6307         IDirect3DPixelShader9_Release(tests[i].shader);
6308     }
6309
6310     IDirect3DVertexDeclaration9_Release(decl);
6311 }
6312
6313 static void test_compare_instructions(IDirect3DDevice9 *device)
6314 {
6315     DWORD shader_sge_vec_code[] = {
6316         0xfffe0101,                                         /* vs_1_1                   */
6317         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6318         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6319         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6320         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
6321         0x0000ffff                                          /* end                      */
6322     };
6323     DWORD shader_slt_vec_code[] = {
6324         0xfffe0101,                                         /* vs_1_1                   */
6325         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6326         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6327         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6328         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
6329         0x0000ffff                                          /* end                      */
6330     };
6331     DWORD shader_sge_scalar_code[] = {
6332         0xfffe0101,                                         /* vs_1_1                   */
6333         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6334         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6335         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6336         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
6337         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
6338         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
6339         0x0000ffff                                          /* end                      */
6340     };
6341     DWORD shader_slt_scalar_code[] = {
6342         0xfffe0101,                                         /* vs_1_1                   */
6343         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6344         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6345         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6346         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
6347         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
6348         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
6349         0x0000ffff                                          /* end                      */
6350     };
6351     IDirect3DVertexShader9 *shader_sge_vec;
6352     IDirect3DVertexShader9 *shader_slt_vec;
6353     IDirect3DVertexShader9 *shader_sge_scalar;
6354     IDirect3DVertexShader9 *shader_slt_scalar;
6355     HRESULT hr, color;
6356     float quad1[] =  {
6357         -1.0,   -1.0,   0.1,
6358          0.0,   -1.0,   0.1,
6359         -1.0,    0.0,   0.1,
6360          0.0,    0.0,   0.1
6361     };
6362     float quad2[] =  {
6363          0.0,   -1.0,   0.1,
6364          1.0,   -1.0,   0.1,
6365          0.0,    0.0,   0.1,
6366          1.0,    0.0,   0.1
6367     };
6368     float quad3[] =  {
6369         -1.0,    0.0,   0.1,
6370          0.0,    0.0,   0.1,
6371         -1.0,    1.0,   0.1,
6372          0.0,    1.0,   0.1
6373     };
6374     float quad4[] =  {
6375          0.0,    0.0,   0.1,
6376          1.0,    0.0,   0.1,
6377          0.0,    1.0,   0.1,
6378          1.0,    1.0,   0.1
6379     };
6380     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6381     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6382
6383     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6384     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6385
6386     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6387     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6388     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6389     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6390     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6391     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6392     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6393     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6394     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6395     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6396     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6397     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6398     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6399     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6400
6401     hr = IDirect3DDevice9_BeginScene(device);
6402     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6403     if(SUCCEEDED(hr))
6404     {
6405         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6406         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6407         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6408         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6409
6410         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6411         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6412         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6413         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6414
6415         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6416         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6417         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6418         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6419
6420         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6421         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6422
6423         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6424         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6425         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6426         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6427
6428         hr = IDirect3DDevice9_EndScene(device);
6429         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6430     }
6431
6432     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6433     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6434
6435     color = getPixelColor(device, 160, 360);
6436     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6437     color = getPixelColor(device, 480, 360);
6438     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6439     color = getPixelColor(device, 160, 120);
6440     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6441     color = getPixelColor(device, 480, 160);
6442     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6443
6444     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6445     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6446
6447     IDirect3DVertexShader9_Release(shader_sge_vec);
6448     IDirect3DVertexShader9_Release(shader_slt_vec);
6449     IDirect3DVertexShader9_Release(shader_sge_scalar);
6450     IDirect3DVertexShader9_Release(shader_slt_scalar);
6451 }
6452
6453 static void test_vshader_input(IDirect3DDevice9 *device)
6454 {
6455     static const DWORD swapped_shader_code_3[] =
6456     {
6457         0xfffe0300,                                         /* vs_3_0               */
6458         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6459         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6460         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6461         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6462         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6463         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6464         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6465         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6466         0x0000ffff                                          /* end                  */
6467     };
6468     static const DWORD swapped_shader_code_1[] =
6469     {
6470         0xfffe0101,                                         /* vs_1_1               */
6471         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6472         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6473         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6474         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6475         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6476         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6477         0x0000ffff                                          /* end                  */
6478     };
6479     static const DWORD swapped_shader_code_2[] =
6480     {
6481         0xfffe0200,                                         /* vs_2_0               */
6482         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6483         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6484         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6485         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6486         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6487         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6488         0x0000ffff                                          /* end                  */
6489     };
6490     static const DWORD texcoord_color_shader_code_3[] =
6491     {
6492         0xfffe0300,                                         /* vs_3_0               */
6493         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6494         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6495         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6496         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6497         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6498         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6499         0x0000ffff                                          /* end                  */
6500     };
6501     static const DWORD texcoord_color_shader_code_2[] =
6502     {
6503         0xfffe0200,                                         /* vs_2_0               */
6504         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6505         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6506         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6507         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6508         0x0000ffff                                          /* end                  */
6509     };
6510     static const DWORD texcoord_color_shader_code_1[] =
6511     {
6512         0xfffe0101,                                         /* vs_1_1               */
6513         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6514         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6515         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6516         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6517         0x0000ffff                                          /* end                  */
6518     };
6519     static const DWORD color_color_shader_code_3[] =
6520     {
6521         0xfffe0300,                                         /* vs_3_0               */
6522         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6523         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6524         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6525         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6526         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6527         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6528         0x0000ffff                                          /* end                  */
6529     };
6530     static const DWORD color_color_shader_code_2[] =
6531     {
6532         0xfffe0200,                                         /* vs_2_0               */
6533         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6534         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6535         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6536         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6537         0x0000ffff                                          /* end                  */
6538     };
6539     static const DWORD color_color_shader_code_1[] =
6540     {
6541         0xfffe0101,                                         /* vs_1_1               */
6542         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6543         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6544         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6545         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6546         0x0000ffff                                          /* end                  */
6547     };
6548     static const DWORD ps3_code[] =
6549     {
6550         0xffff0300,                                         /* ps_3_0               */
6551         0x0200001f, 0x8000000a, 0x900f0000,                 /* dcl_color0 v0        */
6552         0x02000001, 0x800f0800, 0x90e40000,                 /* mov oC0, v0          */
6553         0x0000ffff                                          /* end                  */
6554     };
6555     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6556     IDirect3DPixelShader9 *ps;
6557     HRESULT hr;
6558     DWORD color;
6559     float quad1[] =  {
6560         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6561          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6562         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6563          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6564     };
6565     float quad2[] =  {
6566          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6567          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6568          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6569          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6570     };
6571     float quad3[] =  {
6572         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6573          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6574         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6575          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6576     };
6577     float quad4[] =  {
6578          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6579          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6580          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6581          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6582     };
6583     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6584         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6585         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6586         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6587         D3DDECL_END()
6588     };
6589     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6590         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6591         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6592         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6593         D3DDECL_END()
6594     };
6595     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6596         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6597         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6598         D3DDECL_END()
6599     };
6600     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6601         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6602         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6603         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6604         D3DDECL_END()
6605     };
6606     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6607         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6608         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6609         D3DDECL_END()
6610     };
6611     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6612         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6613         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6614         D3DDECL_END()
6615     };
6616     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6617         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6618         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6619         D3DDECL_END()
6620     };
6621     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6622         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6623         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6624         D3DDECL_END()
6625     };
6626     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6627     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6628     unsigned int i;
6629     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6630     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6631
6632     struct vertex quad1_color[] =  {
6633        {-1.0,   -1.0,   0.1,    0x00ff8040},
6634        { 0.0,   -1.0,   0.1,    0x00ff8040},
6635        {-1.0,    0.0,   0.1,    0x00ff8040},
6636        { 0.0,    0.0,   0.1,    0x00ff8040}
6637     };
6638     struct vertex quad2_color[] =  {
6639        { 0.0,   -1.0,   0.1,    0x00ff8040},
6640        { 1.0,   -1.0,   0.1,    0x00ff8040},
6641        { 0.0,    0.0,   0.1,    0x00ff8040},
6642        { 1.0,    0.0,   0.1,    0x00ff8040}
6643     };
6644     struct vertex quad3_color[] =  {
6645        {-1.0,    0.0,   0.1,    0x00ff8040},
6646        { 0.0,    0.0,   0.1,    0x00ff8040},
6647        {-1.0,    1.0,   0.1,    0x00ff8040},
6648        { 0.0,    1.0,   0.1,    0x00ff8040}
6649     };
6650     float quad4_color[] =  {
6651          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6652          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6653          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6654          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6655     };
6656
6657     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6658     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6659     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6660     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6661     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6662     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6663     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6664     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6665
6666     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6667     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6668     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6669     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6670     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6671     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6672     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6673     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6674
6675     hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
6676     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6677
6678     for(i = 1; i <= 3; i++) {
6679         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6680         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6681         if(i == 3) {
6682             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6683             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6684             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6685             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6686         } else if(i == 2){
6687             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6688             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6689         } else if(i == 1) {
6690             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6691             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6692         }
6693
6694         hr = IDirect3DDevice9_BeginScene(device);
6695         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6696         if(SUCCEEDED(hr))
6697         {
6698             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6699             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6700
6701             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6702             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6703             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6704             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6705
6706             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6707             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6708             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6709             if(i == 3 || i == 2) {
6710                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6711             } else if(i == 1) {
6712                 /* Succeeds or fails, depending on SW or HW vertex processing */
6713                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6714             }
6715
6716             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6717             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6718             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6719             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6720
6721             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6722             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6723             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6724             if(i == 3 || i == 2) {
6725                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6726             } else if(i == 1) {
6727                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6728             }
6729
6730             hr = IDirect3DDevice9_EndScene(device);
6731             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6732         }
6733
6734         if(i == 3 || i == 2) {
6735             color = getPixelColor(device, 160, 360);
6736             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6737                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6738
6739             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6740             color = getPixelColor(device, 480, 360);
6741             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6742                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6743             color = getPixelColor(device, 160, 120);
6744             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6745             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6746                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6747
6748             color = getPixelColor(device, 480, 160);
6749             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6750         } else if(i == 1) {
6751             color = getPixelColor(device, 160, 360);
6752             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6753                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6754             color = getPixelColor(device, 480, 360);
6755             /* Accept the clear color as well in this case, since SW VP returns an error */
6756             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6757             color = getPixelColor(device, 160, 120);
6758             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6759                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6760             color = getPixelColor(device, 480, 160);
6761             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6762         }
6763
6764         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6765         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6766
6767         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6768         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6769
6770         /* Now find out if the whole streams are re-read, or just the last active value for the
6771          * vertices is used.
6772          */
6773         hr = IDirect3DDevice9_BeginScene(device);
6774         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6775         if(SUCCEEDED(hr))
6776         {
6777             float quad1_modified[] =  {
6778                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6779                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6780                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6781                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6782             };
6783             float quad2_modified[] =  {
6784                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6785                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6786                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6787                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6788             };
6789
6790             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6791             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6792
6793             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6794             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6795             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6796             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6797
6798             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6799             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6800             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6801             if(i == 3 || i == 2) {
6802                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6803             } else if(i == 1) {
6804                 /* Succeeds or fails, depending on SW or HW vertex processing */
6805                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6806             }
6807
6808             hr = IDirect3DDevice9_EndScene(device);
6809             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6810         }
6811
6812         color = getPixelColor(device, 480, 350);
6813         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6814          * as well.
6815          *
6816          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6817          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6818          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6819          * refrast's result.
6820          *
6821          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6822          */
6823         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6824            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6825
6826         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6827         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6828
6829         IDirect3DDevice9_SetVertexShader(device, NULL);
6830         IDirect3DDevice9_SetPixelShader(device, NULL);
6831         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6832
6833         IDirect3DVertexShader9_Release(swapped_shader);
6834     }
6835
6836     for(i = 1; i <= 3; i++) {
6837         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6838         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6839         if(i == 3) {
6840             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6841             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6842             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6843             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6844             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6845             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6846         } else if(i == 2){
6847             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6848             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6849             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6850             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6851         } else if(i == 1) {
6852             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6853             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6854             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6855             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6856         }
6857
6858         hr = IDirect3DDevice9_BeginScene(device);
6859         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6860         if(SUCCEEDED(hr))
6861         {
6862             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6863             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6864             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6865             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6866             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6867             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6868
6869             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6870             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6871
6872             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6873             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6874             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6875             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6876             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6877             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6878
6879             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6880             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6881             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6882             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6883             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6884             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6885
6886             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6887             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6888             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6889             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6890
6891             hr = IDirect3DDevice9_EndScene(device);
6892             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6893         }
6894         IDirect3DDevice9_SetVertexShader(device, NULL);
6895         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6896         IDirect3DDevice9_SetPixelShader(device, NULL);
6897
6898         color = getPixelColor(device, 160, 360);
6899         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6900            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6901         color = getPixelColor(device, 480, 360);
6902         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6903            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6904         color = getPixelColor(device, 160, 120);
6905         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6906            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6907         color = getPixelColor(device, 480, 160);
6908         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6909            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6910
6911         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6912         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6913
6914         IDirect3DVertexShader9_Release(texcoord_color_shader);
6915         IDirect3DVertexShader9_Release(color_color_shader);
6916     }
6917
6918     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6919     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6920     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6921     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6922
6923     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6924     IDirect3DVertexDeclaration9_Release(decl_color_color);
6925     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6926     IDirect3DVertexDeclaration9_Release(decl_color_float);
6927
6928     IDirect3DPixelShader9_Release(ps);
6929 }
6930
6931 static void srgbtexture_test(IDirect3DDevice9 *device)
6932 {
6933     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6934      * texture stage state to render a quad using that texture.  The resulting
6935      * color components should be 0x36 (~ 0.21), per this formula:
6936      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6937      * This is true where srgb_color > 0.04045. */
6938     struct IDirect3DTexture9 *texture = NULL;
6939     struct IDirect3DSurface9 *surface = NULL;
6940     IDirect3D9 *d3d = NULL;
6941     HRESULT hr;
6942     D3DLOCKED_RECT lr;
6943     DWORD color;
6944     float quad[] = {
6945         -1.0,       1.0,       0.0,     0.0,    0.0,
6946          1.0,       1.0,       0.0,     1.0,    0.0,
6947         -1.0,      -1.0,       0.0,     0.0,    1.0,
6948          1.0,      -1.0,       0.0,     1.0,    1.0,
6949     };
6950
6951
6952     memset(&lr, 0, sizeof(lr));
6953     IDirect3DDevice9_GetDirect3D(device, &d3d);
6954     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6955                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6956                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6957         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6958         goto out;
6959     }
6960
6961     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6962                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6963                                         &texture, NULL);
6964     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6965     if(!texture) {
6966         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6967         goto out;
6968     }
6969     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6970     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6971
6972     fill_surface(surface, 0xff7f7f7f);
6973     IDirect3DSurface9_Release(surface);
6974
6975     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6976     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6977     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6978     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6979
6980     hr = IDirect3DDevice9_BeginScene(device);
6981     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6982     if(SUCCEEDED(hr))
6983     {
6984         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6985         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6986
6987         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6988         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6989
6990
6991         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6992         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6993
6994         hr = IDirect3DDevice9_EndScene(device);
6995         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6996     }
6997
6998     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6999     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
7000     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
7001     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
7002
7003     color = getPixelColor(device, 320, 240);
7004     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
7005
7006     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7007     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7008
7009 out:
7010     if(texture) IDirect3DTexture9_Release(texture);
7011     IDirect3D9_Release(d3d);
7012 }
7013
7014 static void shademode_test(IDirect3DDevice9 *device)
7015 {
7016     /* Render a quad and try all of the different fixed function shading models. */
7017     struct IDirect3DVertexBuffer9 *vb_strip = NULL;
7018     struct IDirect3DVertexBuffer9 *vb_list = NULL;
7019     HRESULT hr;
7020     DWORD color0, color1;
7021     DWORD color0_gouraud = 0, color1_gouraud = 0;
7022     DWORD shademode = D3DSHADE_FLAT;
7023     DWORD primtype = D3DPT_TRIANGLESTRIP;
7024     LPVOID data = NULL;
7025     UINT i, j;
7026     struct vertex quad_strip[] =
7027     {
7028         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
7029         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
7030         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
7031         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
7032     };
7033     struct vertex quad_list[] =
7034     {
7035         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
7036         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
7037         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
7038
7039         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
7040         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
7041         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
7042     };
7043
7044     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
7045                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
7046     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7047     if (FAILED(hr)) goto bail;
7048
7049     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
7050                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
7051     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7052     if (FAILED(hr)) goto bail;
7053
7054     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7055     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7056
7057     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7058     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7059
7060     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
7061     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7062     memcpy(data, quad_strip, sizeof(quad_strip));
7063     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
7064     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7065
7066     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
7067     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7068     memcpy(data, quad_list, sizeof(quad_list));
7069     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
7070     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7071
7072     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
7073      * the color fixups we have to do for FLAT shading will be dependent on that. */
7074     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
7075     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7076
7077     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
7078     for (j=0; j<2; j++) {
7079
7080         /* Inner loop just changes the D3DRS_SHADEMODE */
7081         for (i=0; i<3; i++) {
7082             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7083             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7084
7085             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
7086             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7087
7088             hr = IDirect3DDevice9_BeginScene(device);
7089             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7090             if(SUCCEEDED(hr))
7091             {
7092                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
7093                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
7094
7095                 hr = IDirect3DDevice9_EndScene(device);
7096                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7097             }
7098
7099             /* Sample two spots from the output */
7100             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
7101             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
7102             switch(shademode) {
7103                 case D3DSHADE_FLAT:
7104                     /* Should take the color of the first vertex of each triangle */
7105                     if (0)
7106                     {
7107                         /* This test depends on EXT_provoking_vertex being
7108                          * available. This extension is currently (20090810)
7109                          * not common enough to let the test fail if it isn't
7110                          * present. */
7111                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
7112                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
7113                     }
7114                     shademode = D3DSHADE_GOURAUD;
7115                     break;
7116                 case D3DSHADE_GOURAUD:
7117                     /* Should be an interpolated blend */
7118
7119                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7120                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
7121                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7122                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
7123
7124                     color0_gouraud = color0;
7125                     color1_gouraud = color1;
7126
7127                     shademode = D3DSHADE_PHONG;
7128                     break;
7129                 case D3DSHADE_PHONG:
7130                     /* Should be the same as GOURAUD, since no hardware implements this */
7131                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7132                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
7133                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7134                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7135
7136                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7137                             color0_gouraud, color0);
7138                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7139                             color1_gouraud, color1);
7140                     break;
7141             }
7142         }
7143
7144         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7145         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7146
7147         /* Now, do it all over again with a TRIANGLELIST */
7148         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7149         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7150         primtype = D3DPT_TRIANGLELIST;
7151         shademode = D3DSHADE_FLAT;
7152     }
7153
7154 bail:
7155     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7156     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7157     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7158     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7159
7160     if (vb_strip)
7161         IDirect3DVertexBuffer9_Release(vb_strip);
7162     if (vb_list)
7163         IDirect3DVertexBuffer9_Release(vb_list);
7164 }
7165
7166 static void alpha_test(IDirect3DDevice9 *device)
7167 {
7168     HRESULT hr;
7169     IDirect3DTexture9 *offscreenTexture;
7170     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7171     DWORD color;
7172
7173     struct vertex quad1[] =
7174     {
7175         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
7176         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
7177         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
7178         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
7179     };
7180     struct vertex quad2[] =
7181     {
7182         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
7183         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
7184         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
7185         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
7186     };
7187     static const float composite_quad[][5] = {
7188         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7189         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
7190         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7191         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
7192     };
7193
7194     /* Clear the render target with alpha = 0.5 */
7195     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7196     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7197
7198     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7199     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7200
7201     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7202     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7203     if(!backbuffer) {
7204         goto out;
7205     }
7206
7207     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7208     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7209     if(!offscreen) {
7210         goto out;
7211     }
7212
7213     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7214     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7215
7216     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7217     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7218     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7219     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7220     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7221     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7222     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7223     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7224     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7225     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7226
7227     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7228     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7229     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7230
7231         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7232         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7233         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7234         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7235         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7236         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7237         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7238
7239         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7240         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7241         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7242         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7243         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7244         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7245
7246         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7247          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7248          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7249         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7250         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7251         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7252         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7253
7254         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7255         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7256         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7257         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7258         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7259         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7260
7261         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7262         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7263         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7264         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7265         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7266         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7267
7268         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7269         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7270
7271         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7272          * Disable alpha blending for the final composition
7273          */
7274         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7275         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7276         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7277         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7278
7279         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7280         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7281         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7282         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7283         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7284         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7285
7286         hr = IDirect3DDevice9_EndScene(device);
7287         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7288     }
7289
7290     color = getPixelColor(device, 160, 360);
7291     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7292        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7293
7294     color = getPixelColor(device, 160, 120);
7295     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7296        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7297
7298     color = getPixelColor(device, 480, 360);
7299     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7300        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7301
7302     color = getPixelColor(device, 480, 120);
7303     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7304        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7305
7306     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7307
7308     out:
7309     /* restore things */
7310     if(backbuffer) {
7311         IDirect3DSurface9_Release(backbuffer);
7312     }
7313     if(offscreenTexture) {
7314         IDirect3DTexture9_Release(offscreenTexture);
7315     }
7316     if(offscreen) {
7317         IDirect3DSurface9_Release(offscreen);
7318     }
7319 }
7320
7321 struct vertex_shortcolor {
7322     float x, y, z;
7323     unsigned short r, g, b, a;
7324 };
7325 struct vertex_floatcolor {
7326     float x, y, z;
7327     float r, g, b, a;
7328 };
7329
7330 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7331 {
7332     HRESULT hr;
7333     BOOL s_ok, ub_ok, f_ok;
7334     DWORD color, size, i;
7335     void *data;
7336     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7337         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7338         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7339         D3DDECL_END()
7340     };
7341     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7342         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7343         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7344         D3DDECL_END()
7345     };
7346     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7347         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7348         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7349         D3DDECL_END()
7350     };
7351     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7352         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7353         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7354         D3DDECL_END()
7355     };
7356     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7357         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7358         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7359         D3DDECL_END()
7360     };
7361     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7362         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7363         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7364         D3DDECL_END()
7365     };
7366     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7367         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
7368         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7369         D3DDECL_END()
7370     };
7371     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7372     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7373     IDirect3DVertexBuffer9 *vb, *vb2;
7374     struct vertex quad1[] =                             /* D3DCOLOR */
7375     {
7376         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
7377         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7378         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
7379         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7380     };
7381     struct vertex quad2[] =                             /* UBYTE4N */
7382     {
7383         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7384         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
7385         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7386         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
7387     };
7388     struct vertex_shortcolor quad3[] =                  /* short */
7389     {
7390         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7391         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7392         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7393         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7394     };
7395     struct vertex_floatcolor quad4[] =
7396     {
7397         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7398         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7399         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7400         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7401     };
7402     DWORD colors[] = {
7403         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7404         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7405         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7406         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7407         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7408         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7409         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7410         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7411         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7412         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7413         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7414         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7415         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7416         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7417         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7418         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7419     };
7420     float quads[] = {
7421         -1.0,   -1.0,     0.1,
7422         -1.0,    0.0,     0.1,
7423          0.0,   -1.0,     0.1,
7424          0.0,    0.0,     0.1,
7425
7426          0.0,   -1.0,     0.1,
7427          0.0,    0.0,     0.1,
7428          1.0,   -1.0,     0.1,
7429          1.0,    0.0,     0.1,
7430
7431          0.0,    0.0,     0.1,
7432          0.0,    1.0,     0.1,
7433          1.0,    0.0,     0.1,
7434          1.0,    1.0,     0.1,
7435
7436         -1.0,    0.0,     0.1,
7437         -1.0,    1.0,     0.1,
7438          0.0,    0.0,     0.1,
7439          0.0,    1.0,     0.1
7440     };
7441     struct tvertex quad_transformed[] = {
7442        {  90,    110,     0.1,      2.0,        0x00ffff00},
7443        { 570,    110,     0.1,      2.0,        0x00ffff00},
7444        {  90,    300,     0.1,      2.0,        0x00ffff00},
7445        { 570,    300,     0.1,      2.0,        0x00ffff00}
7446     };
7447     D3DCAPS9 caps;
7448
7449     memset(&caps, 0, sizeof(caps));
7450     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7451     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7452
7453     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7454     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7455
7456     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7457     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7458     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7459     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7460     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7461     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7462     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7463         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7464         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7465         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7466         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7467     } else {
7468         trace("D3DDTCAPS_UBYTE4N not supported\n");
7469         dcl_ubyte_2 = NULL;
7470         dcl_ubyte = NULL;
7471     }
7472     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7473     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7474     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7475     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7476
7477     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7478     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7479                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7480     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7481
7482     hr = IDirect3DDevice9_BeginScene(device);
7483     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7484     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7485     if(SUCCEEDED(hr)) {
7486         if(dcl_color) {
7487             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7488             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7489             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7490             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7491         }
7492
7493         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7494          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7495          * using software vertex processing. Doh!
7496          */
7497         if(dcl_ubyte) {
7498             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7499             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7500             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7501             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7502             ub_ok = SUCCEEDED(hr);
7503         }
7504
7505         if(dcl_short) {
7506             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7507             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7508             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7509             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7510             s_ok = SUCCEEDED(hr);
7511         }
7512
7513         if(dcl_float) {
7514             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7515             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7516             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7517             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7518             f_ok = SUCCEEDED(hr);
7519         }
7520
7521         hr = IDirect3DDevice9_EndScene(device);
7522         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7523     }
7524
7525     if(dcl_short) {
7526         color = getPixelColor(device, 480, 360);
7527         ok(color == 0x000000ff || !s_ok,
7528            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7529     }
7530     if(dcl_ubyte) {
7531         color = getPixelColor(device, 160, 120);
7532         ok(color == 0x0000ffff || !ub_ok,
7533            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7534     }
7535     if(dcl_color) {
7536         color = getPixelColor(device, 160, 360);
7537         ok(color == 0x00ffff00,
7538            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7539     }
7540     if(dcl_float) {
7541         color = getPixelColor(device, 480, 120);
7542         ok(color == 0x00ff0000 || !f_ok,
7543            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7544     }
7545     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7546
7547     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7548      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7549      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7550      * whether the immediate mode code works
7551      */
7552     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7553     hr = IDirect3DDevice9_BeginScene(device);
7554     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7555     if(SUCCEEDED(hr)) {
7556         if(dcl_color) {
7557             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7558             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7559             memcpy(data, quad1, sizeof(quad1));
7560             hr = IDirect3DVertexBuffer9_Unlock(vb);
7561             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7562             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7563             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7564             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7565             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7566             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7567             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7568         }
7569
7570         if(dcl_ubyte) {
7571             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7572             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7573             memcpy(data, quad2, sizeof(quad2));
7574             hr = IDirect3DVertexBuffer9_Unlock(vb);
7575             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7576             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7577             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7578             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7579             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7580             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7581             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7582                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7583             ub_ok = SUCCEEDED(hr);
7584         }
7585
7586         if(dcl_short) {
7587             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7588             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7589             memcpy(data, quad3, sizeof(quad3));
7590             hr = IDirect3DVertexBuffer9_Unlock(vb);
7591             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7592             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7593             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7594             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7595             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7596             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7597             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7598                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7599             s_ok = SUCCEEDED(hr);
7600         }
7601
7602         if(dcl_float) {
7603             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7604             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7605             memcpy(data, quad4, sizeof(quad4));
7606             hr = IDirect3DVertexBuffer9_Unlock(vb);
7607             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7608             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7609             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7610             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7611             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7612             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7613             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7614                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7615             f_ok = SUCCEEDED(hr);
7616         }
7617
7618         hr = IDirect3DDevice9_EndScene(device);
7619         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7620     }
7621
7622     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7623     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7624     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7625     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7626
7627     if(dcl_short) {
7628         color = getPixelColor(device, 480, 360);
7629         ok(color == 0x000000ff || !s_ok,
7630            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7631     }
7632     if(dcl_ubyte) {
7633         color = getPixelColor(device, 160, 120);
7634         ok(color == 0x0000ffff || !ub_ok,
7635            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7636     }
7637     if(dcl_color) {
7638         color = getPixelColor(device, 160, 360);
7639         ok(color == 0x00ffff00,
7640            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7641     }
7642     if(dcl_float) {
7643         color = getPixelColor(device, 480, 120);
7644         ok(color == 0x00ff0000 || !f_ok,
7645            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7646     }
7647     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7648
7649     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7650     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7651
7652     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7653     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7654     memcpy(data, quad_transformed, sizeof(quad_transformed));
7655     hr = IDirect3DVertexBuffer9_Unlock(vb);
7656     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7657
7658     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7659     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7660
7661     hr = IDirect3DDevice9_BeginScene(device);
7662     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7663     if(SUCCEEDED(hr)) {
7664         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7665         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7666         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7667         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7668
7669         hr = IDirect3DDevice9_EndScene(device);
7670         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7671     }
7672
7673     color = getPixelColor(device, 88, 108);
7674     ok(color == 0x000000ff,
7675        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7676     color = getPixelColor(device, 92, 108);
7677     ok(color == 0x000000ff,
7678        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7679     color = getPixelColor(device, 88, 112);
7680     ok(color == 0x000000ff,
7681        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7682     color = getPixelColor(device, 92, 112);
7683     ok(color == 0x00ffff00,
7684        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7685
7686     color = getPixelColor(device, 568, 108);
7687     ok(color == 0x000000ff,
7688        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7689     color = getPixelColor(device, 572, 108);
7690     ok(color == 0x000000ff,
7691        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7692     color = getPixelColor(device, 568, 112);
7693     ok(color == 0x00ffff00,
7694        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7695     color = getPixelColor(device, 572, 112);
7696     ok(color == 0x000000ff,
7697        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7698
7699     color = getPixelColor(device, 88, 298);
7700     ok(color == 0x000000ff,
7701        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7702     color = getPixelColor(device, 92, 298);
7703     ok(color == 0x00ffff00,
7704        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7705     color = getPixelColor(device, 88, 302);
7706     ok(color == 0x000000ff,
7707        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7708     color = getPixelColor(device, 92, 302);
7709     ok(color == 0x000000ff,
7710        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7711
7712     color = getPixelColor(device, 568, 298);
7713     ok(color == 0x00ffff00,
7714        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7715     color = getPixelColor(device, 572, 298);
7716     ok(color == 0x000000ff,
7717        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7718     color = getPixelColor(device, 568, 302);
7719     ok(color == 0x000000ff,
7720        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7721     color = getPixelColor(device, 572, 302);
7722     ok(color == 0x000000ff,
7723        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7724
7725     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7726
7727     /* This test is pointless without those two declarations: */
7728     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7729         skip("color-ubyte switching test declarations aren't supported\n");
7730         goto out;
7731     }
7732
7733     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7734     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7735     memcpy(data, quads, sizeof(quads));
7736     hr = IDirect3DVertexBuffer9_Unlock(vb);
7737     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7738     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7739                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7740     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7741     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7742     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7743     memcpy(data, colors, sizeof(colors));
7744     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7745     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7746
7747     for(i = 0; i < 2; i++) {
7748         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7749         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7750
7751         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7752         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7753         if(i == 0) {
7754             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7755         } else {
7756             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7757         }
7758         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7759
7760         hr = IDirect3DDevice9_BeginScene(device);
7761         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7762         ub_ok = FALSE;
7763         if(SUCCEEDED(hr)) {
7764             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7765             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7766             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7767             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7768                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7769             ub_ok = SUCCEEDED(hr);
7770
7771             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7772             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7773             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7774             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7775
7776             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7777             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7778             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7779             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7780                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7781             ub_ok = (SUCCEEDED(hr) && ub_ok);
7782
7783             hr = IDirect3DDevice9_EndScene(device);
7784             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7785         }
7786
7787         if(i == 0) {
7788             color = getPixelColor(device, 480, 360);
7789             ok(color == 0x00ff0000,
7790                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7791             color = getPixelColor(device, 160, 120);
7792             ok(color == 0x00ffffff,
7793                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7794             color = getPixelColor(device, 160, 360);
7795             ok(color == 0x000000ff || !ub_ok,
7796                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7797             color = getPixelColor(device, 480, 120);
7798             ok(color == 0x000000ff || !ub_ok,
7799                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7800         } else {
7801             color = getPixelColor(device, 480, 360);
7802             ok(color == 0x000000ff,
7803                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7804             color = getPixelColor(device, 160, 120);
7805             ok(color == 0x00ffffff,
7806                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7807             color = getPixelColor(device, 160, 360);
7808             ok(color == 0x00ff0000 || !ub_ok,
7809                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7810             color = getPixelColor(device, 480, 120);
7811             ok(color == 0x00ff0000 || !ub_ok,
7812                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7813         }
7814         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7815     }
7816
7817     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7818     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7819     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7820     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7821     IDirect3DVertexBuffer9_Release(vb2);
7822
7823     out:
7824     IDirect3DVertexBuffer9_Release(vb);
7825     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7826     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7827     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7828     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7829     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7830     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7831     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7832 }
7833
7834 struct vertex_float16color {
7835     float x, y, z;
7836     DWORD c1, c2;
7837 };
7838
7839 static void test_vshader_float16(IDirect3DDevice9 *device)
7840 {
7841     HRESULT hr;
7842     DWORD color;
7843     void *data;
7844     static const D3DVERTEXELEMENT9 decl_elements[] = {
7845         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7846         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7847         D3DDECL_END()
7848     };
7849     IDirect3DVertexDeclaration9 *vdecl = NULL;
7850     IDirect3DVertexBuffer9 *buffer = NULL;
7851     IDirect3DVertexShader9 *shader;
7852     DWORD shader_code[] = {
7853         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7854         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7855         0x90e40001, 0x0000ffff
7856     };
7857     struct vertex_float16color quad[] = {
7858         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7859         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7860         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7861         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7862
7863         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7864         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7865         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7866         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7867
7868         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7869         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7870         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7871         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7872
7873         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7874         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7875         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7876         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7877     };
7878
7879     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7880     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7881
7882     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7883     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7884     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7885     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7886     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7887     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7888
7889     hr = IDirect3DDevice9_BeginScene(device);
7890     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7891     if(SUCCEEDED(hr)) {
7892         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7893         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7894         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7895         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7896         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7897         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7898         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7899         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7900         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7901         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7902
7903         hr = IDirect3DDevice9_EndScene(device);
7904         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7905     }
7906     color = getPixelColor(device, 480, 360);
7907     ok(color == 0x00ff0000,
7908        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7909     color = getPixelColor(device, 160, 120);
7910     ok(color == 0x00000000,
7911        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7912     color = getPixelColor(device, 160, 360);
7913     ok(color == 0x0000ff00,
7914        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7915     color = getPixelColor(device, 480, 120);
7916     ok(color == 0x000000ff,
7917        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7918     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7919
7920     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7921     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7922
7923     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7924                                              D3DPOOL_MANAGED, &buffer, NULL);
7925     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7926     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7927     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7928     memcpy(data, quad, sizeof(quad));
7929     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7930     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7931     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7932     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7933
7934     hr = IDirect3DDevice9_BeginScene(device);
7935     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7936     if(SUCCEEDED(hr)) {
7937             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7938             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7939             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7940             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7941             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7942             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7943             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7944             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7945
7946             hr = IDirect3DDevice9_EndScene(device);
7947             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7948     }
7949
7950     color = getPixelColor(device, 480, 360);
7951     ok(color == 0x00ff0000,
7952        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7953     color = getPixelColor(device, 160, 120);
7954     ok(color == 0x00000000,
7955        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7956     color = getPixelColor(device, 160, 360);
7957     ok(color == 0x0000ff00,
7958        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7959     color = getPixelColor(device, 480, 120);
7960     ok(color == 0x000000ff,
7961        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7962     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7963
7964     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7965     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7966     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7967     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7968     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7969     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7970
7971     IDirect3DVertexDeclaration9_Release(vdecl);
7972     IDirect3DVertexShader9_Release(shader);
7973     IDirect3DVertexBuffer9_Release(buffer);
7974 }
7975
7976 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7977 {
7978     D3DCAPS9 caps;
7979     IDirect3DTexture9 *texture;
7980     HRESULT hr;
7981     D3DLOCKED_RECT rect;
7982     unsigned int x, y;
7983     DWORD *dst, color;
7984     const float quad[] = {
7985         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7986          1.0,   -1.0,   0.1,    1.2,   -0.2,
7987         -1.0,    1.0,   0.1,   -0.2,    1.2,
7988          1.0,    1.0,   0.1,    1.2,    1.2
7989     };
7990     memset(&caps, 0, sizeof(caps));
7991
7992     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7993     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7994     if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
7995     {
7996         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7997         ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
7998                 "Card has conditional NP2 support without power of two restriction set\n");
7999     }
8000     else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
8001     {
8002         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
8003         return;
8004     }
8005     else
8006     {
8007         skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
8008         return;
8009     }
8010
8011     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8012     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8013
8014     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
8015     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8016
8017     memset(&rect, 0, sizeof(rect));
8018     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
8019     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8020     for(y = 0; y < 10; y++) {
8021         for(x = 0; x < 10; x++) {
8022             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
8023             if(x == 0 || x == 9 || y == 0 || y == 9) {
8024                 *dst = 0x00ff0000;
8025             } else {
8026                 *dst = 0x000000ff;
8027             }
8028         }
8029     }
8030     hr = IDirect3DTexture9_UnlockRect(texture, 0);
8031     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8032
8033     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8034     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8035     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
8036     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8037     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
8038     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8039     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8040     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8041
8042     hr = IDirect3DDevice9_BeginScene(device);
8043     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8044     if(SUCCEEDED(hr)) {
8045         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8046         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8047
8048         hr = IDirect3DDevice9_EndScene(device);
8049         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8050     }
8051
8052     color = getPixelColor(device,    1,  1);
8053     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
8054     color = getPixelColor(device, 639, 479);
8055     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
8056
8057     color = getPixelColor(device, 135, 101);
8058     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
8059     color = getPixelColor(device, 140, 101);
8060     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
8061     color = getPixelColor(device, 135, 105);
8062     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
8063     color = getPixelColor(device, 140, 105);
8064     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
8065
8066     color = getPixelColor(device, 135, 376);
8067     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
8068     color = getPixelColor(device, 140, 376);
8069     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
8070     color = getPixelColor(device, 135, 379);
8071     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
8072     color = getPixelColor(device, 140, 379);
8073     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
8074
8075     color = getPixelColor(device, 500, 101);
8076     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
8077     color = getPixelColor(device, 504, 101);
8078     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
8079     color = getPixelColor(device, 500, 105);
8080     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
8081     color = getPixelColor(device, 504, 105);
8082     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
8083
8084     color = getPixelColor(device, 500, 376);
8085     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
8086     color = getPixelColor(device, 504, 376);
8087     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
8088     color = getPixelColor(device, 500, 380);
8089     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
8090     color = getPixelColor(device, 504, 380);
8091     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
8092
8093     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8094
8095     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8096     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8097     IDirect3DTexture9_Release(texture);
8098 }
8099
8100 static void vFace_register_test(IDirect3DDevice9 *device)
8101 {
8102     HRESULT hr;
8103     DWORD color;
8104     const DWORD shader_code[] = {
8105         0xffff0300,                                                             /* ps_3_0                     */
8106         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8107         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
8108         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
8109         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
8110         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
8111         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8112         0x0000ffff                                                              /* END                        */
8113     };
8114     const DWORD vshader_code[] = {
8115         0xfffe0300,                                                             /* vs_3_0               */
8116         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8117         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8118         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8119         0x0000ffff                                                              /* end                  */
8120     };
8121     IDirect3DPixelShader9 *shader;
8122     IDirect3DVertexShader9 *vshader;
8123     IDirect3DTexture9 *texture;
8124     IDirect3DSurface9 *surface, *backbuffer;
8125     const float quad[] = {
8126         -1.0,   -1.0,   0.1,
8127          1.0,   -1.0,   0.1,
8128         -1.0,    0.0,   0.1,
8129
8130          1.0,   -1.0,   0.1,
8131          1.0,    0.0,   0.1,
8132         -1.0,    0.0,   0.1,
8133
8134         -1.0,    0.0,   0.1,
8135         -1.0,    1.0,   0.1,
8136          1.0,    0.0,   0.1,
8137
8138          1.0,    0.0,   0.1,
8139         -1.0,    1.0,   0.1,
8140          1.0,    1.0,   0.1,
8141     };
8142     const float blit[] = {
8143          0.0,   -1.0,   0.1,    0.0,    0.0,
8144          1.0,   -1.0,   0.1,    1.0,    0.0,
8145          0.0,    1.0,   0.1,    0.0,    1.0,
8146          1.0,    1.0,   0.1,    1.0,    1.0,
8147     };
8148
8149     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8150     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8151     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8152     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8153     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8154     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8155     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8156     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8157     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8158     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8159     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8160     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8161     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8162     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8163     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8164     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8165
8166     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8167     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8168
8169     hr = IDirect3DDevice9_BeginScene(device);
8170     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8171     if(SUCCEEDED(hr)) {
8172         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8173         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8174         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8175         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8176         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8177         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8178         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8179         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8180         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8181         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8182         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8183
8184         /* Blit the texture onto the back buffer to make it visible */
8185         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8186         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
8187         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8188         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8189         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8190         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8191         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8192         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8193         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8194         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8195         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8196         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8197
8198         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8199         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8200
8201         hr = IDirect3DDevice9_EndScene(device);
8202         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8203     }
8204
8205     color = getPixelColor(device, 160, 360);
8206     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8207     color = getPixelColor(device, 160, 120);
8208     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8209     color = getPixelColor(device, 480, 360);
8210     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8211     color = getPixelColor(device, 480, 120);
8212     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8213     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8214     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8215
8216     IDirect3DDevice9_SetTexture(device, 0, NULL);
8217     IDirect3DPixelShader9_Release(shader);
8218     IDirect3DVertexShader9_Release(vshader);
8219     IDirect3DSurface9_Release(surface);
8220     IDirect3DSurface9_Release(backbuffer);
8221     IDirect3DTexture9_Release(texture);
8222 }
8223
8224 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8225 {
8226     HRESULT hr;
8227     DWORD color;
8228     int i;
8229     D3DCAPS9 caps;
8230     BOOL L6V5U5_supported = FALSE;
8231     IDirect3DTexture9 *tex1, *tex2;
8232     D3DLOCKED_RECT locked_rect;
8233
8234     static const float quad[][7] = {
8235         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8236         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8237         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8238         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8239     };
8240
8241     static const D3DVERTEXELEMENT9 decl_elements[] = {
8242         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8243         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8244         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8245         D3DDECL_END()
8246     };
8247
8248     /* use asymmetric matrix to test loading */
8249     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8250     float scale, offset;
8251
8252     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8253     IDirect3DTexture9           *texture            = NULL;
8254
8255     memset(&caps, 0, sizeof(caps));
8256     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8257     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8258     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8259         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8260         return;
8261     } else {
8262         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8263          * They report that it is not supported, but after that bump mapping works properly. So just test
8264          * if the format is generally supported, and check the BUMPENVMAP flag
8265          */
8266         IDirect3D9 *d3d9;
8267
8268         IDirect3DDevice9_GetDirect3D(device, &d3d9);
8269         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8270                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8271         L6V5U5_supported = SUCCEEDED(hr);
8272         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8273                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8274         IDirect3D9_Release(d3d9);
8275         if(FAILED(hr)) {
8276             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8277             return;
8278         }
8279     }
8280
8281     /* Generate the textures */
8282     generate_bumpmap_textures(device);
8283
8284     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8285     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8286     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8287     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8288     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8289     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8290     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8291     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8292
8293     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8294     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8295     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8296     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8297     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8298     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8299
8300     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8301     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8302     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8303     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8304     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8305     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8306
8307     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8308     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8309
8310     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8311     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8312
8313     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8314     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8315
8316
8317     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8318     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8319     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8320     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8321
8322     hr = IDirect3DDevice9_BeginScene(device);
8323     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8324
8325     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8326     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8327
8328     hr = IDirect3DDevice9_EndScene(device);
8329     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8330
8331     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8332      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8333      * But since testing the color match is not the purpose of the test don't be too picky
8334      */
8335     color = getPixelColor(device, 320-32, 240);
8336     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8337     color = getPixelColor(device, 320+32, 240);
8338     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8339     color = getPixelColor(device, 320, 240-32);
8340     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8341     color = getPixelColor(device, 320, 240+32);
8342     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8343     color = getPixelColor(device, 320, 240);
8344     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8345     color = getPixelColor(device, 320+32, 240+32);
8346     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8347     color = getPixelColor(device, 320-32, 240+32);
8348     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8349     color = getPixelColor(device, 320+32, 240-32);
8350     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8351     color = getPixelColor(device, 320-32, 240-32);
8352     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8353     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8354     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8355
8356     for(i = 0; i < 2; i++) {
8357         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8358         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8359         IDirect3DTexture9_Release(texture); /* For the GetTexture */
8360         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8361         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8362         IDirect3DTexture9_Release(texture); /* To destroy it */
8363     }
8364
8365     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8366         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8367         goto cleanup;
8368     }
8369     if(L6V5U5_supported == FALSE) {
8370         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8371         goto cleanup;
8372     }
8373
8374     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8375     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8376     /* This test only tests the luminance part. The bumpmapping part was already tested above and
8377      * would only make this test more complicated
8378      */
8379     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8380     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8381     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8382     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8383
8384     memset(&locked_rect, 0, sizeof(locked_rect));
8385     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8386     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8387     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8388     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8389     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8390
8391     memset(&locked_rect, 0, sizeof(locked_rect));
8392     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8393     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8394     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8395     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8396     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8397
8398     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8399     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8400     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8401     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8402
8403     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8404     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8405     scale = 2.0;
8406     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8407     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8408     offset = 0.1;
8409     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8410     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8411
8412     hr = IDirect3DDevice9_BeginScene(device);
8413     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8414     if(SUCCEEDED(hr)) {
8415         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8416         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8417         hr = IDirect3DDevice9_EndScene(device);
8418         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8419     }
8420
8421     color = getPixelColor(device, 320, 240);
8422     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
8423      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
8424      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8425      */
8426     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8427     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8428     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8429
8430     /* Check a result scale factor > 1.0 */
8431     scale = 10;
8432     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8433     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8434     offset = 10;
8435     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8436     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8437
8438     hr = IDirect3DDevice9_BeginScene(device);
8439     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8440     if(SUCCEEDED(hr)) {
8441         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8442         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8443         hr = IDirect3DDevice9_EndScene(device);
8444         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8445     }
8446     color = getPixelColor(device, 320, 240);
8447     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8448     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8449     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8450
8451     /* Check clamping in the scale factor calculation */
8452     scale = 1000;
8453     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8454     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8455     offset = -1;
8456     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8457     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8458
8459     hr = IDirect3DDevice9_BeginScene(device);
8460     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8461     if(SUCCEEDED(hr)) {
8462         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8463         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8464         hr = IDirect3DDevice9_EndScene(device);
8465         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8466     }
8467     color = getPixelColor(device, 320, 240);
8468     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8469     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8470     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8471
8472     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8473     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8474     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8475     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8476
8477     IDirect3DTexture9_Release(tex1);
8478     IDirect3DTexture9_Release(tex2);
8479
8480 cleanup:
8481     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8482     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8483     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8484     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8485
8486     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8487     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8488     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8489 }
8490
8491 static void stencil_cull_test(IDirect3DDevice9 *device) {
8492     HRESULT hr;
8493     IDirect3DSurface9 *depthstencil = NULL;
8494     D3DSURFACE_DESC desc;
8495     float quad1[] = {
8496         -1.0,   -1.0,   0.1,
8497          0.0,   -1.0,   0.1,
8498         -1.0,    0.0,   0.1,
8499          0.0,    0.0,   0.1,
8500     };
8501     float quad2[] = {
8502          0.0,   -1.0,   0.1,
8503          1.0,   -1.0,   0.1,
8504          0.0,    0.0,   0.1,
8505          1.0,    0.0,   0.1,
8506     };
8507     float quad3[] = {
8508         0.0,    0.0,   0.1,
8509         1.0,    0.0,   0.1,
8510         0.0,    1.0,   0.1,
8511         1.0,    1.0,   0.1,
8512     };
8513     float quad4[] = {
8514         -1.0,    0.0,   0.1,
8515          0.0,    0.0,   0.1,
8516         -1.0,    1.0,   0.1,
8517          0.0,    1.0,   0.1,
8518     };
8519     struct vertex painter[] = {
8520        {-1.0,   -1.0,   0.0,    0x00000000},
8521        { 1.0,   -1.0,   0.0,    0x00000000},
8522        {-1.0,    1.0,   0.0,    0x00000000},
8523        { 1.0,    1.0,   0.0,    0x00000000},
8524     };
8525     WORD indices_cw[]  = {0, 1, 3};
8526     WORD indices_ccw[] = {0, 2, 3};
8527     unsigned int i;
8528     DWORD color;
8529
8530     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8531     if(depthstencil == NULL) {
8532         skip("No depth stencil buffer\n");
8533         return;
8534     }
8535     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8536     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8537     IDirect3DSurface9_Release(depthstencil);
8538     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8539         skip("No 4 or 8 bit stencil surface\n");
8540         return;
8541     }
8542
8543     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8544     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8545     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8546     ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
8547
8548     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8549     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8550     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8551     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8552     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8553     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8554     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8555     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8556
8557     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8558     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8559     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8560     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8561     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8562     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8563
8564     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8565     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8566     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8567     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8568
8569     /* First pass: Fill the stencil buffer with some values... */
8570     hr = IDirect3DDevice9_BeginScene(device);
8571     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8572     if(SUCCEEDED(hr))
8573     {
8574         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8575         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8576         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8577                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8578         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8579         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8580                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8581         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8582
8583         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8584         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8585         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8586         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8587         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8588                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8589         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8590         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8591                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8592         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8593
8594         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8595         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8596         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8597                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8598         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8599         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8600                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8601         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8602
8603         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8604         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8605         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8606                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8607         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8608         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8609                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8610         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8611
8612         hr = IDirect3DDevice9_EndScene(device);
8613         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8614     }
8615
8616     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8617     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8618     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8619     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8620     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8621     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8622     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8623     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8624     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8625     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8626     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8627     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8628
8629     /* 2nd pass: Make the stencil values visible */
8630     hr = IDirect3DDevice9_BeginScene(device);
8631     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8632     if(SUCCEEDED(hr))
8633     {
8634         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8635         ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8636         for (i = 0; i < 16; ++i)
8637         {
8638             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8639             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8640
8641             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8642             painter[1].diffuse = (i * 16);
8643             painter[2].diffuse = (i * 16);
8644             painter[3].diffuse = (i * 16);
8645             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8646             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8647         }
8648         hr = IDirect3DDevice9_EndScene(device);
8649         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8650     }
8651
8652     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8653     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8654
8655     color = getPixelColor(device, 160, 420);
8656     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8657     color = getPixelColor(device, 160, 300);
8658     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8659
8660     color = getPixelColor(device, 480, 420);
8661     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8662     color = getPixelColor(device, 480, 300);
8663     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8664
8665     color = getPixelColor(device, 160, 180);
8666     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8667     color = getPixelColor(device, 160, 60);
8668     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8669
8670     color = getPixelColor(device, 480, 180);
8671     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8672     color = getPixelColor(device, 480, 60);
8673     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8674
8675     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8676     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8677 }
8678
8679 static void vpos_register_test(IDirect3DDevice9 *device)
8680 {
8681     HRESULT hr;
8682     DWORD color;
8683     const DWORD shader_code[] = {
8684     0xffff0300,                                                             /* ps_3_0                     */
8685     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8686     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8687     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8688     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8689     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8690     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8691     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8692     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8693     0x0000ffff                                                              /* end                        */
8694     };
8695     const DWORD shader_frac_code[] = {
8696     0xffff0300,                                                             /* ps_3_0                     */
8697     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8698     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8699     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8700     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8701     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8702     0x0000ffff                                                              /* end                        */
8703     };
8704     const DWORD vshader_code[] = {
8705         0xfffe0300,                                                             /* vs_3_0               */
8706         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8707         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8708         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8709         0x0000ffff                                                              /* end                  */
8710     };
8711     IDirect3DVertexShader9 *vshader;
8712     IDirect3DPixelShader9 *shader, *shader_frac;
8713     IDirect3DSurface9 *surface = NULL, *backbuffer;
8714     const float quad[] = {
8715         -1.0,   -1.0,   0.1,    0.0,    0.0,
8716          1.0,   -1.0,   0.1,    1.0,    0.0,
8717         -1.0,    1.0,   0.1,    0.0,    1.0,
8718          1.0,    1.0,   0.1,    1.0,    1.0,
8719     };
8720     D3DLOCKED_RECT lr;
8721     float constant[4] = {1.0, 0.0, 320, 240};
8722     DWORD *pos;
8723
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_CreateVertexShader(device, vshader_code, &vshader);
8727     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8728     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8729     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8730     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8731     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8732     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8733     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8734     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8735     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8736     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8737     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8738     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8739     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8740
8741     hr = IDirect3DDevice9_BeginScene(device);
8742     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8743     if(SUCCEEDED(hr)) {
8744         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8745         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8746         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8747         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8748         hr = IDirect3DDevice9_EndScene(device);
8749         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8750     }
8751
8752     /* This has to be pixel exact */
8753     color = getPixelColor(device, 319, 239);
8754     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8755     color = getPixelColor(device, 320, 239);
8756     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8757     color = getPixelColor(device, 319, 240);
8758     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8759     color = getPixelColor(device, 320, 240);
8760     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8761     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8762
8763     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8764                                              &surface, NULL);
8765     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8766     hr = IDirect3DDevice9_BeginScene(device);
8767     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8768     if(SUCCEEDED(hr)) {
8769         constant[2] = 16; constant[3] = 16;
8770         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8771         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8772         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8773         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8774         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8775         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8776         hr = IDirect3DDevice9_EndScene(device);
8777         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8778     }
8779     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8780     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8781
8782     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8783     color = *pos & 0x00ffffff;
8784     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8785     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8786     color = *pos & 0x00ffffff;
8787     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8788     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8789     color = *pos & 0x00ffffff;
8790     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8791     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8792     color = *pos & 0x00ffffff;
8793     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8794
8795     hr = IDirect3DSurface9_UnlockRect(surface);
8796     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8797
8798     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8799      * have full control over the multisampling setting inside this test
8800      */
8801     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8802     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8803     hr = IDirect3DDevice9_BeginScene(device);
8804     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8805     if(SUCCEEDED(hr)) {
8806         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8807         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8808         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8809         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8810         hr = IDirect3DDevice9_EndScene(device);
8811         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8812     }
8813     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8814     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8815
8816     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8817     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8818
8819     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8820     color = *pos & 0x00ffffff;
8821     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8822
8823     hr = IDirect3DSurface9_UnlockRect(surface);
8824     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8825
8826     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8827     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8828     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8829     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8830     IDirect3DPixelShader9_Release(shader);
8831     IDirect3DPixelShader9_Release(shader_frac);
8832     IDirect3DVertexShader9_Release(vshader);
8833     if(surface) IDirect3DSurface9_Release(surface);
8834     IDirect3DSurface9_Release(backbuffer);
8835 }
8836
8837 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8838 {
8839     D3DCOLOR color;
8840
8841     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8842     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8843     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8844     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8845     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8846
8847     ++r;
8848     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8849     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8850     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8851     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8852     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8853
8854     return TRUE;
8855 }
8856
8857 static void pointsize_test(IDirect3DDevice9 *device)
8858 {
8859     HRESULT hr;
8860     D3DCAPS9 caps;
8861     D3DMATRIX matrix;
8862     D3DMATRIX identity;
8863     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8864     DWORD color;
8865     IDirect3DSurface9 *rt, *backbuffer;
8866     IDirect3DTexture9 *tex1, *tex2;
8867     RECT rect = {0, 0, 128, 128};
8868     D3DLOCKED_RECT lr;
8869     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8870                                 0x00000000, 0x00000000};
8871     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8872                                 0x00000000, 0x0000ff00};
8873
8874     const float vertices[] = {
8875         64,     64,     0.1,
8876         128,    64,     0.1,
8877         192,    64,     0.1,
8878         256,    64,     0.1,
8879         320,    64,     0.1,
8880         384,    64,     0.1,
8881         448,    64,     0.1,
8882         512,    64,     0.1,
8883     };
8884
8885     /* 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 */
8886     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;
8887     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;
8888     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;
8889     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;
8890
8891     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;
8892     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;
8893     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;
8894     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;
8895
8896     memset(&caps, 0, sizeof(caps));
8897     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8898     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8899     if(caps.MaxPointSize < 32.0) {
8900         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8901         return;
8902     }
8903
8904     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8905     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8906     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8907     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8908     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8909     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8910     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8911     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8912
8913     hr = IDirect3DDevice9_BeginScene(device);
8914     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8915     if (SUCCEEDED(hr))
8916     {
8917         ptsize = 15.0;
8918         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8919         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8920         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8921         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8922
8923         ptsize = 31.0;
8924         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8925         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8926         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8927         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8928
8929         ptsize = 30.75;
8930         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8931         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8932         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8933         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8934
8935         if (caps.MaxPointSize >= 63.0)
8936         {
8937             ptsize = 63.0;
8938             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8939             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8940             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8941             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8942
8943             ptsize = 62.75;
8944             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8945             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8946             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8947             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8948         }
8949
8950         ptsize = 1.0;
8951         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8952         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8953         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8954         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8955
8956         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8957         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8958         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8959         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8960
8961         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8962         ptsize = 15.0;
8963         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8964         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8965         ptsize = 1.0;
8966         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8967         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8968         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8969         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8970
8971         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8972         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8973
8974         /* pointsize < pointsize_min < pointsize_max?
8975          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8976         ptsize = 1.0;
8977         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8978         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8979         ptsize = 15.0;
8980         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8981         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8982         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8983         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8984
8985         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8986         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8987
8988         hr = IDirect3DDevice9_EndScene(device);
8989         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8990     }
8991
8992     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8993     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8994     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8995
8996     if (caps.MaxPointSize >= 63.0)
8997     {
8998         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8999         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
9000     }
9001
9002     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
9003     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
9004     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
9005     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
9006     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
9007
9008     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9009
9010     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
9011      * generates texture coordinates for the point(result: Yes, it does)
9012      *
9013      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
9014      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
9015      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
9016      */
9017     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
9018     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9019
9020     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
9021     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9022     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9023     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9024     memset(&lr, 0, sizeof(lr));
9025     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
9026     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9027     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
9028     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9029     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9030     memset(&lr, 0, sizeof(lr));
9031     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
9032     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9033     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
9034     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9035     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9036     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9037     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9038     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9039     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9040     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9041     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9042     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9043     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9044     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9045     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9046     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9047     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9048     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9049     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9050
9051     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
9052     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9053     ptsize = 32.0;
9054     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9055     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9056
9057     hr = IDirect3DDevice9_BeginScene(device);
9058     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9059     if(SUCCEEDED(hr))
9060     {
9061         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9062         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9063         hr = IDirect3DDevice9_EndScene(device);
9064         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9065     }
9066
9067     color = getPixelColor(device, 64-4, 64-4);
9068     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
9069     color = getPixelColor(device, 64-4, 64+4);
9070     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
9071     color = getPixelColor(device, 64+4, 64+4);
9072     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
9073     color = getPixelColor(device, 64+4, 64-4);
9074     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
9075     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9076
9077     U(matrix).m[0][0] =  1.0f / 64.0f;
9078     U(matrix).m[1][1] = -1.0f / 64.0f;
9079     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
9080     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
9081
9082     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
9083     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
9084
9085     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
9086             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
9087     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
9088
9089     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
9090     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9091     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
9092     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
9093
9094     hr = IDirect3DDevice9_BeginScene(device);
9095     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9096     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9097     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9098     hr = IDirect3DDevice9_EndScene(device);
9099     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9100
9101     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
9102     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
9103     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9104     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9105     IDirect3DSurface9_Release(backbuffer);
9106     IDirect3DSurface9_Release(rt);
9107
9108     color = getPixelColor(device, 64-4, 64-4);
9109     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
9110             "Expected color 0x00ff0000, got 0x%08x.\n", color);
9111     color = getPixelColor(device, 64+4, 64-4);
9112     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
9113             "Expected color 0x00ffff00, got 0x%08x.\n", color);
9114     color = getPixelColor(device, 64-4, 64+4);
9115     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
9116             "Expected color 0x00000000, got 0x%08x.\n", color);
9117     color = getPixelColor(device, 64+4, 64+4);
9118     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9119             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9120
9121     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9122     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9123
9124     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9125     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9126     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9127     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9128     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9129     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9130     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9131     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9132     IDirect3DTexture9_Release(tex1);
9133     IDirect3DTexture9_Release(tex2);
9134
9135     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9136     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9137     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9138     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9139     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9140     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9141 }
9142
9143 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9144 {
9145     static const DWORD vshader_code[] =
9146     {
9147         0xfffe0300,                                                             /* vs_3_0                     */
9148         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0            */
9149         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0            */
9150         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                 */
9151         0x0000ffff                                                              /* end                        */
9152     };
9153     static const DWORD pshader_code1[] =
9154     {
9155         0xffff0300,                                                             /* ps_3_0                     */
9156         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9157         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
9158         0x0000ffff                                                              /* end                        */
9159     };
9160     static const DWORD pshader_code2[] =
9161     {
9162         0xffff0300,                                                             /* ps_3_0                     */
9163         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9164         0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
9165         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
9166         0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1                */
9167         0x0000ffff                                                              /* end                        */
9168     };
9169
9170     HRESULT hr;
9171     IDirect3DVertexShader9 *vs;
9172     IDirect3DPixelShader9 *ps1, *ps2;
9173     IDirect3DTexture9 *tex1, *tex2;
9174     IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
9175     D3DCAPS9 caps;
9176     DWORD color;
9177     UINT i, j;
9178     float quad[] = {
9179        -1.0,   -1.0,    0.1,
9180         1.0,   -1.0,    0.1,
9181        -1.0,    1.0,    0.1,
9182         1.0,    1.0,    0.1,
9183     };
9184     float texquad[] = {
9185        -1.0,   -1.0,    0.1,    0.0,    0.0,
9186         0.0,   -1.0,    0.1,    1.0,    0.0,
9187        -1.0,    1.0,    0.1,    0.0,    1.0,
9188         0.0,    1.0,    0.1,    1.0,    1.0,
9189
9190         0.0,   -1.0,    0.1,    0.0,    0.0,
9191         1.0,   -1.0,    0.1,    1.0,    0.0,
9192         0.0,    1.0,    0.1,    0.0,    1.0,
9193         1.0,    1.0,    0.1,    1.0,    1.0,
9194     };
9195
9196     memset(&caps, 0, sizeof(caps));
9197     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9198     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9199     if(caps.NumSimultaneousRTs < 2) {
9200         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9201         return;
9202     }
9203
9204     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9205     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9206
9207     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
9208             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
9209     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
9210
9211     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9212             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9213     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9214     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9215             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9216     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9217     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
9218     ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
9219     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
9220     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9221     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
9222     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9223
9224     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9225     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9226     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9227     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9228     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9229     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9230
9231     hr = IDirect3DDevice9_SetVertexShader(device, vs);
9232     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9233     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9234     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9235     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9236     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9237     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9238     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9239
9240     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
9241     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9242     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9243     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9244     color = getPixelColorFromSurface(readback, 8, 8);
9245     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9246             "Expected color 0x000000ff, got 0x%08x.\n", color);
9247     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9248     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9249     color = getPixelColorFromSurface(readback, 8, 8);
9250     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9251             "Expected color 0x000000ff, got 0x%08x.\n", color);
9252
9253     /* Render targets not written by the pixel shader should be unmodified. */
9254     hr = IDirect3DDevice9_SetPixelShader(device, ps1);
9255     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9256     hr = IDirect3DDevice9_BeginScene(device);
9257     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9258     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9259     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9260     hr = IDirect3DDevice9_EndScene(device);
9261     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9262     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9263     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9264     color = getPixelColorFromSurface(readback, 8, 8);
9265     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9266             "Expected color 0xff00ff00, got 0x%08x.\n", color);
9267     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9268     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9269     for (i = 6; i < 10; ++i)
9270     {
9271         for (j = 6; j < 10; ++j)
9272         {
9273             color = getPixelColorFromSurface(readback, j, i);
9274             ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9275                     "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
9276         }
9277     }
9278
9279     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9280     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9281     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9282     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9283     color = getPixelColorFromSurface(readback, 8, 8);
9284     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9285             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9286     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9287     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9288     color = getPixelColorFromSurface(readback, 8, 8);
9289     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9290             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9291
9292     hr = IDirect3DDevice9_SetPixelShader(device, ps2);
9293     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9294
9295     hr = IDirect3DDevice9_BeginScene(device);
9296     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9297     if(SUCCEEDED(hr)) {
9298         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9299         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9300
9301         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9302         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9303         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9304         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9305         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9306         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9307         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9308         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9309         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9310         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9311
9312         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9313         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9314         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9315         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9316
9317         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9318         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9319         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9320         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9321
9322         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9323         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9324
9325         hr = IDirect3DDevice9_EndScene(device);
9326         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9327     }
9328
9329     color = getPixelColor(device, 160, 240);
9330     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9331     color = getPixelColor(device, 480, 240);
9332     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9333     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9334
9335     IDirect3DPixelShader9_Release(ps2);
9336     IDirect3DPixelShader9_Release(ps1);
9337     IDirect3DVertexShader9_Release(vs);
9338     IDirect3DTexture9_Release(tex1);
9339     IDirect3DTexture9_Release(tex2);
9340     IDirect3DSurface9_Release(surf1);
9341     IDirect3DSurface9_Release(surf2);
9342     IDirect3DSurface9_Release(backbuf);
9343     IDirect3DSurface9_Release(readback);
9344 }
9345
9346 struct formats {
9347     const char *fmtName;
9348     D3DFORMAT textureFormat;
9349     DWORD resultColorBlending;
9350     DWORD resultColorNoBlending;
9351 };
9352
9353 static const struct formats test_formats[] = {
9354   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9355   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9356   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9357   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9358   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9359   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9360   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9361   { NULL, 0 }
9362 };
9363
9364 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9365 {
9366     HRESULT hr;
9367     IDirect3DTexture9 *offscreenTexture = NULL;
9368     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9369     IDirect3D9 *d3d = NULL;
9370     DWORD color;
9371     DWORD r0, g0, b0, r1, g1, b1;
9372     int fmt_index;
9373
9374     static const float quad[][5] = {
9375         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9376         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
9377         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9378         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
9379     };
9380
9381     /* Quad with R=0x10, G=0x20 */
9382     static const struct vertex quad1[] = {
9383         {-1.0f, -1.0f, 0.1f, 0x80102000},
9384         {-1.0f,  1.0f, 0.1f, 0x80102000},
9385         { 1.0f, -1.0f, 0.1f, 0x80102000},
9386         { 1.0f,  1.0f, 0.1f, 0x80102000},
9387     };
9388
9389     /* Quad with R=0x20, G=0x10 */
9390     static const struct vertex quad2[] = {
9391         {-1.0f, -1.0f, 0.1f, 0x80201000},
9392         {-1.0f,  1.0f, 0.1f, 0x80201000},
9393         { 1.0f, -1.0f, 0.1f, 0x80201000},
9394         { 1.0f,  1.0f, 0.1f, 0x80201000},
9395     };
9396
9397     IDirect3DDevice9_GetDirect3D(device, &d3d);
9398
9399     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9400     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9401     if(!backbuffer) {
9402         goto out;
9403     }
9404
9405     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9406     {
9407         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9408
9409         if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9410                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
9411         {
9412             skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
9413             continue;
9414         }
9415
9416         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9417         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9418
9419         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9420         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9421         if(!offscreenTexture) {
9422             continue;
9423         }
9424
9425         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9426         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9427         if(!offscreen) {
9428             continue;
9429         }
9430
9431         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9432         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9433
9434         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9435         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9436         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9437         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9438         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9439         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9440         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9441         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9442         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9443         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9444
9445         /* Below we will draw two quads with different colors and try to blend them together.
9446          * The result color is compared with the expected outcome.
9447          */
9448         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9449             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9450             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9451             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9452             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9453
9454             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9455             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9456
9457             /* Draw a quad using color 0x0010200 */
9458             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9459             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9460             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9461             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9462             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9463             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9464
9465             /* Draw a quad using color 0x0020100 */
9466             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9467             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9468             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9469             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9470             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9471             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9472
9473             /* We don't want to blend the result on the backbuffer */
9474             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9475             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9476
9477             /* Prepare rendering the 'blended' texture quad to the backbuffer */
9478             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9479             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9480             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9481             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9482
9483             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9484             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9485
9486             /* This time with the texture */
9487             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9488             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9489
9490             IDirect3DDevice9_EndScene(device);
9491         }
9492
9493         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9494             /* Compare the color of the center quad with our expectation */
9495             color = getPixelColor(device, 320, 240);
9496             r0 = (color & 0x00ff0000) >> 16;
9497             g0 = (color & 0x0000ff00) >>  8;
9498             b0 = (color & 0x000000ff) >>  0;
9499
9500             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9501             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9502             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9503
9504             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9505                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9506                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9507                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9508         } else {
9509             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9510              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9511              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9512             color = getPixelColor(device, 320, 240);
9513             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);
9514         }
9515         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9516
9517         IDirect3DDevice9_SetTexture(device, 0, NULL);
9518         if(offscreenTexture) {
9519             IDirect3DTexture9_Release(offscreenTexture);
9520         }
9521         if(offscreen) {
9522             IDirect3DSurface9_Release(offscreen);
9523         }
9524     }
9525
9526 out:
9527     /* restore things */
9528     if(backbuffer) {
9529         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9530         IDirect3DSurface9_Release(backbuffer);
9531     }
9532 }
9533
9534 static void tssargtemp_test(IDirect3DDevice9 *device)
9535 {
9536     HRESULT hr;
9537     DWORD color;
9538     static const struct vertex quad[] = {
9539         {-1.0,     -1.0,    0.1,    0x00ff0000},
9540         { 1.0,     -1.0,    0.1,    0x00ff0000},
9541         {-1.0,      1.0,    0.1,    0x00ff0000},
9542         { 1.0,      1.0,    0.1,    0x00ff0000}
9543     };
9544     D3DCAPS9 caps;
9545
9546     memset(&caps, 0, sizeof(caps));
9547     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9548     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9549     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9550         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9551         return;
9552     }
9553
9554     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9555     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9556
9557     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9558     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9559     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9560     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9561
9562     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9563     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9564     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9565     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9566     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9567     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9568
9569     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9570     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9571     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9572     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9573     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9574     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9575
9576     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9577     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9578
9579     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9580     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9581     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9582     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9583
9584     hr = IDirect3DDevice9_BeginScene(device);
9585     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9586     if(SUCCEEDED(hr)) {
9587         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9588         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9589         hr = IDirect3DDevice9_EndScene(device);
9590         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9591     }
9592     color = getPixelColor(device, 320, 240);
9593     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9594     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9595
9596     /* Set stage 1 back to default */
9597     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9598     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9599     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9600     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9601     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9602     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9603     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9604     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9605     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9606     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9607 }
9608
9609 struct testdata
9610 {
9611     DWORD idxVertex; /* number of instances in the first stream */
9612     DWORD idxColor; /* number of instances in the second stream */
9613     DWORD idxInstance; /* should be 1 ?? */
9614     DWORD color1; /* color 1 instance */
9615     DWORD color2; /* color 2 instance */
9616     DWORD color3; /* color 3 instance */
9617     DWORD color4; /* color 4 instance */
9618     WORD strVertex; /* specify which stream to use 0-2*/
9619     WORD strColor;
9620     WORD strInstance;
9621 };
9622
9623 static const struct testdata testcases[]=
9624 {
9625     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9626     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9627     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9628     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9629     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  4 */
9630     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9631     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9632     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9633     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  8 */
9634     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /*  9 */
9635     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9636     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9637     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9638     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9639 /*
9640     This draws one instance on some machines, no instance on others
9641     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9642 */
9643 /*
9644     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9645     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9646 */
9647 };
9648
9649 /* Drawing Indexed Geometry with instances*/
9650 static void stream_test(IDirect3DDevice9 *device)
9651 {
9652     IDirect3DVertexBuffer9 *vb = NULL;
9653     IDirect3DVertexBuffer9 *vb2 = NULL;
9654     IDirect3DVertexBuffer9 *vb3 = NULL;
9655     IDirect3DIndexBuffer9 *ib = NULL;
9656     IDirect3DVertexDeclaration9 *pDecl = NULL;
9657     IDirect3DVertexShader9 *shader = NULL;
9658     HRESULT hr;
9659     BYTE *data;
9660     DWORD color;
9661     DWORD ind;
9662     unsigned i;
9663
9664     const DWORD shader_code[] =
9665     {
9666         0xfffe0101,                                     /* vs_1_1 */
9667         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9668         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9669         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9670         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9671         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9672         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9673         0x0000ffff
9674     };
9675
9676     const float quad[][3] =
9677     {
9678         {-0.5f, -0.5f,  1.1f}, /*0 */
9679         {-0.5f,  0.5f,  1.1f}, /*1 */
9680         { 0.5f, -0.5f,  1.1f}, /*2 */
9681         { 0.5f,  0.5f,  1.1f}, /*3 */
9682     };
9683
9684     const float vertcolor[][4] =
9685     {
9686         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9687         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9688         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9689         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9690     };
9691
9692     /* 4 position for 4 instances */
9693     const float instancepos[][3] =
9694     {
9695         {-0.6f,-0.6f, 0.0f},
9696         { 0.6f,-0.6f, 0.0f},
9697         { 0.6f, 0.6f, 0.0f},
9698         {-0.6f, 0.6f, 0.0f},
9699     };
9700
9701     short indices[] = {0, 1, 2, 1, 2, 3};
9702
9703     D3DVERTEXELEMENT9 decl[] =
9704     {
9705         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9706         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9707         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9708         D3DDECL_END()
9709     };
9710
9711     /* set the default value because it isn't done in wine? */
9712     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9713     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9714
9715     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9716     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9717     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9718
9719     /* check wrong cases */
9720     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9721     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9722     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9723     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9724     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9725     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9726     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9727     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9728     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9729     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9730     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9731     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9732     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9733     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9734     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9735     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9736     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9737     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9738     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9739     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9740
9741     /* set the default value back */
9742     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9743     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9744
9745     /* create all VertexBuffers*/
9746     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9747     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9748     if(!vb) {
9749         skip("Failed to create a vertex buffer\n");
9750         return;
9751     }
9752     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9753     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9754     if(!vb2) {
9755         skip("Failed to create a vertex buffer\n");
9756         goto out;
9757     }
9758     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9759     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9760     if(!vb3) {
9761         skip("Failed to create a vertex buffer\n");
9762         goto out;
9763     }
9764
9765     /* create IndexBuffer*/
9766     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9767     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9768     if(!ib) {
9769         skip("Failed to create a index buffer\n");
9770         goto out;
9771     }
9772
9773     /* copy all Buffers (Vertex + Index)*/
9774     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9775     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9776     memcpy(data, quad, sizeof(quad));
9777     hr = IDirect3DVertexBuffer9_Unlock(vb);
9778     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9779     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9780     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9781     memcpy(data, vertcolor, sizeof(vertcolor));
9782     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9783     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9784     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9785     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9786     memcpy(data, instancepos, sizeof(instancepos));
9787     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9788     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9789     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9790     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9791     memcpy(data, indices, sizeof(indices));
9792     hr = IDirect3DIndexBuffer9_Unlock(ib);
9793     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9794
9795     /* create VertexShader */
9796     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9797     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9798     if(!shader) {
9799         skip("Failed to create a vetex shader\n");
9800         goto out;
9801     }
9802
9803     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9804     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9805
9806     hr = IDirect3DDevice9_SetIndices(device, ib);
9807     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9808
9809     /* run all tests */
9810     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9811     {
9812         struct testdata act = testcases[i];
9813         decl[0].Stream = act.strVertex;
9814         decl[1].Stream = act.strColor;
9815         decl[2].Stream = act.strInstance;
9816         /* create VertexDeclarations */
9817         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9818         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9819
9820         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9821         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9822
9823         hr = IDirect3DDevice9_BeginScene(device);
9824         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9825         if(SUCCEEDED(hr))
9826         {
9827             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9828             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9829
9830             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9831             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9832             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9833             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9834
9835             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9836             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9837             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9838             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9839
9840             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9841             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9842             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9843             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9844
9845             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9846             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9847             hr = IDirect3DDevice9_EndScene(device);
9848             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9849
9850             /* set all StreamSource && StreamSourceFreq back to default */
9851             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9852             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9853             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9854             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9855             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9856             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9857             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9858             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9859             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9860             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9861             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9862             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9863         }
9864
9865         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9866         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9867
9868         color = getPixelColor(device, 160, 360);
9869         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9870         color = getPixelColor(device, 480, 360);
9871         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9872         color = getPixelColor(device, 480, 120);
9873         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9874         color = getPixelColor(device, 160, 120);
9875         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9876
9877         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9878         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9879     }
9880
9881     hr = IDirect3DDevice9_SetIndices(device, NULL);
9882     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9883
9884 out:
9885     if(vb) IDirect3DVertexBuffer9_Release(vb);
9886     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9887     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9888     if(ib)IDirect3DIndexBuffer9_Release(ib);
9889     if(shader)IDirect3DVertexShader9_Release(shader);
9890 }
9891
9892 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9893     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9894     IDirect3DTexture9 *dsttex = NULL;
9895     HRESULT hr;
9896     DWORD color;
9897     D3DRECT r1 = {0,  0,  50,  50 };
9898     D3DRECT r2 = {50, 0,  100, 50 };
9899     D3DRECT r3 = {50, 50, 100, 100};
9900     D3DRECT r4 = {0,  50,  50, 100};
9901     const float quad[] = {
9902         -1.0,   -1.0,   0.1,    0.0,    0.0,
9903          1.0,   -1.0,   0.1,    1.0,    0.0,
9904         -1.0,    1.0,   0.1,    0.0,    1.0,
9905          1.0,    1.0,   0.1,    1.0,    1.0,
9906     };
9907
9908     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9909     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9910
9911     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9912     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9913     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9914     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9915
9916     if(!src || !dsttex) {
9917         skip("One or more test resources could not be created\n");
9918         goto cleanup;
9919     }
9920
9921     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9922     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9923
9924     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9925     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9926
9927     /* Clear the StretchRect destination for debugging */
9928     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9929     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9930     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9931     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9932
9933     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9934     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9935
9936     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9937     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9938     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9939     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9940     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9941     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9942     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9943     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9944
9945     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9946      * the target -> texture GL blit path
9947      */
9948     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9949     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9950     IDirect3DSurface9_Release(dst);
9951
9952     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9953     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9954
9955     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9956     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9957     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9958     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9959     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9960     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9961     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9962     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9963
9964     hr = IDirect3DDevice9_BeginScene(device);
9965     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9966     if(SUCCEEDED(hr)) {
9967         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9968         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9969         hr = IDirect3DDevice9_EndScene(device);
9970         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9971     }
9972
9973     color = getPixelColor(device, 160, 360);
9974     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9975     color = getPixelColor(device, 480, 360);
9976     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9977     color = getPixelColor(device, 480, 120);
9978     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9979     color = getPixelColor(device, 160, 120);
9980     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9981     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9982     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9983
9984     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9985     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9986     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9987     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9988
9989 cleanup:
9990     if(src) IDirect3DSurface9_Release(src);
9991     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9992     if(dsttex) IDirect3DTexture9_Release(dsttex);
9993 }
9994
9995 static void texop_test(IDirect3DDevice9 *device)
9996 {
9997     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9998     IDirect3DTexture9 *texture = NULL;
9999     D3DLOCKED_RECT locked_rect;
10000     D3DCOLOR color;
10001     D3DCAPS9 caps;
10002     HRESULT hr;
10003     unsigned i;
10004
10005     static const struct {
10006         float x, y, z;
10007         float s, t;
10008         D3DCOLOR diffuse;
10009     } quad[] = {
10010         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10011         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10012         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10013         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
10014     };
10015
10016     static const D3DVERTEXELEMENT9 decl_elements[] = {
10017         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10018         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
10019         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
10020         D3DDECL_END()
10021     };
10022
10023     static const struct {
10024         D3DTEXTUREOP op;
10025         const char *name;
10026         DWORD caps_flag;
10027         D3DCOLOR result;
10028     } test_data[] = {
10029         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10030         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
10031         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
10032         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
10033         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10034         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10035         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
10036         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10037         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10038         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10039         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10040         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
10041         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
10042         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10043         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10044         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
10045         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
10046         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10047         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
10048         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
10049         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
10050         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
10051         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
10052     };
10053
10054     memset(&caps, 0, sizeof(caps));
10055     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10056     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10057
10058     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
10059     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
10060     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
10061     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
10062
10063     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10064     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10065     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10066     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10067     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
10068     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10069     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10070     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10071     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10072
10073     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
10074     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10075     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10076     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10077     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10078     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10079
10080     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10081     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10082
10083     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10084     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10085     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
10086     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10087     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
10088     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10089
10090     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10091     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10092
10093     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
10094     {
10095         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
10096         {
10097             skip("tex operation %s not supported\n", test_data[i].name);
10098             continue;
10099         }
10100
10101         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
10102         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
10103
10104         hr = IDirect3DDevice9_BeginScene(device);
10105         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10106
10107         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10108         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10109
10110         hr = IDirect3DDevice9_EndScene(device);
10111         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10112
10113         color = getPixelColor(device, 320, 240);
10114         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
10115                 test_data[i].name, color, test_data[i].result);
10116
10117         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10118         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10119     }
10120
10121     if (texture) IDirect3DTexture9_Release(texture);
10122     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
10123 }
10124
10125 static void yuv_color_test(IDirect3DDevice9 *device) {
10126     HRESULT hr;
10127     IDirect3DSurface9 *surface = NULL, *target = NULL;
10128     unsigned int fmt, i;
10129     D3DFORMAT format;
10130     const char *fmt_string;
10131     D3DLOCKED_RECT lr;
10132     IDirect3D9 *d3d;
10133     HRESULT color;
10134     DWORD ref_color_left, ref_color_right;
10135
10136     struct {
10137         DWORD in;           /* The input color */
10138         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
10139         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
10140         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
10141         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
10142     } test_data[] = {
10143     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
10144      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
10145      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
10146      * that
10147      */
10148       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
10149       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
10150       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
10151       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
10152       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
10153       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
10154       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
10155       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
10156       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
10157       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
10158       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
10159       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
10160       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
10161       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
10162
10163       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
10164       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
10165       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
10166       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
10167     };
10168
10169     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
10170     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
10171     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
10172     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
10173
10174     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
10175     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10176
10177     for(fmt = 0; fmt < 2; fmt++) {
10178         if(fmt == 0) {
10179             format = D3DFMT_UYVY;
10180             fmt_string = "D3DFMT_UYVY";
10181         } else {
10182             format = D3DFMT_YUY2;
10183             fmt_string = "D3DFMT_YUY2";
10184         }
10185
10186         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
10187                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
10188                        */
10189         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
10190                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
10191             skip("%s is not supported\n", fmt_string);
10192             continue;
10193         }
10194
10195         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
10196         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
10197         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
10198
10199         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
10200             if(fmt == 0) {
10201                 ref_color_left = test_data[i].uyvy_left;
10202                 ref_color_right = test_data[i].uyvy_right;
10203             } else {
10204                 ref_color_left = test_data[i].yuy2_left;
10205                 ref_color_right = test_data[i].yuy2_right;
10206             }
10207
10208             memset(&lr, 0, sizeof(lr));
10209             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
10210             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
10211             *((DWORD *) lr.pBits) = test_data[i].in;
10212             hr = IDirect3DSurface9_UnlockRect(surface);
10213             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10214
10215             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10216             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10217             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10218             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10219
10220             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10221              * prevent running into precision problems, read a far left and far right pixel. In the future we may
10222              * want to add tests for the filtered pixels as well.
10223              *
10224              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10225              * differently, so we need a max diff of 16
10226              */
10227             color = getPixelColor(device, 40, 240);
10228
10229             /* Newer versions of the Nvidia Windows driver mix up the U and V channels, breaking all the tests
10230              * where U != V. Skip the entire test if this bug in this case
10231              */
10232             if (broken(test_data[i].in == 0xff000000 && color == 0x00008800 && format == D3DFMT_UYVY))
10233             {
10234                 skip("Nvidia channel confusion bug detected, skipping YUV tests\n");
10235                 IDirect3DSurface9_Release(surface);
10236                 goto out;
10237             }
10238
10239             ok(color_match(color, ref_color_left, 18),
10240                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10241                test_data[i].in, color, ref_color_left, fmt_string);
10242             color = getPixelColor(device, 600, 240);
10243             ok(color_match(color, ref_color_right, 18),
10244                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10245                test_data[i].in, color, ref_color_right, fmt_string);
10246             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10247             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10248         }
10249         IDirect3DSurface9_Release(surface);
10250     }
10251
10252 out:
10253     IDirect3DSurface9_Release(target);
10254     IDirect3D9_Release(d3d);
10255 }
10256
10257 static void texop_range_test(IDirect3DDevice9 *device)
10258 {
10259     static const struct {
10260         float x, y, z;
10261         D3DCOLOR diffuse;
10262     } quad[] = {
10263         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10264         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10265         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10266         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10267     };
10268     HRESULT hr;
10269     IDirect3DTexture9 *texture;
10270     D3DLOCKED_RECT locked_rect;
10271     D3DCAPS9 caps;
10272     DWORD color;
10273
10274     /* We need ADD and SUBTRACT operations */
10275     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10276     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10277     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10278         skip("D3DTOP_ADD is not supported, skipping value range test\n");
10279         return;
10280     }
10281     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10282         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10283         return;
10284     }
10285
10286     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10287     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10288     /* Stage 1: result = diffuse(=1.0) + diffuse
10289      * stage 2: result = result - tfactor(= 0.5)
10290      */
10291     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10292     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10293     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10294     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10295     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10296     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10297     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10298     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10299     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10300     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10301     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10302     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10303     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10304     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10305
10306     hr = IDirect3DDevice9_BeginScene(device);
10307     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10308     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10309     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10310     hr = IDirect3DDevice9_EndScene(device);
10311     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10312
10313     color = getPixelColor(device, 320, 240);
10314     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10315        color);
10316     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10317     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10318
10319     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10320     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10321     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10322     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10323     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10324     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10325     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10326     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10327     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10328
10329     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10330      * stage 2: result = result + diffuse(1.0)
10331      */
10332     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10333     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10334     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10335     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10336     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10337     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10338     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10339     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10340     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10341     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10342     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10343     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10344     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10345     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10346
10347     hr = IDirect3DDevice9_BeginScene(device);
10348     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10349     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10350     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10351     hr = IDirect3DDevice9_EndScene(device);
10352     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10353
10354     color = getPixelColor(device, 320, 240);
10355     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10356        color);
10357     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10358     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10359
10360     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10361     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10362     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10363     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10364     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10365     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10366     IDirect3DTexture9_Release(texture);
10367 }
10368
10369 static void alphareplicate_test(IDirect3DDevice9 *device) {
10370     struct vertex quad[] = {
10371         { -1.0,    -1.0,    0.1,    0x80ff00ff },
10372         {  1.0,    -1.0,    0.1,    0x80ff00ff },
10373         { -1.0,     1.0,    0.1,    0x80ff00ff },
10374         {  1.0,     1.0,    0.1,    0x80ff00ff },
10375     };
10376     HRESULT hr;
10377     DWORD color;
10378
10379     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10380     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10381
10382     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10383     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10384
10385     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10386     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10387     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10388     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10389
10390     hr = IDirect3DDevice9_BeginScene(device);
10391     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10392     if(SUCCEEDED(hr)) {
10393         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10394         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10395         hr = IDirect3DDevice9_EndScene(device);
10396         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10397     }
10398
10399     color = getPixelColor(device, 320, 240);
10400     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10401        color);
10402     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10403     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10404
10405     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10406     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10407
10408 }
10409
10410 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10411     HRESULT hr;
10412     D3DCAPS9 caps;
10413     DWORD color;
10414     struct vertex quad[] = {
10415         { -1.0,    -1.0,    0.1,    0x408080c0 },
10416         {  1.0,    -1.0,    0.1,    0x408080c0 },
10417         { -1.0,     1.0,    0.1,    0x408080c0 },
10418         {  1.0,     1.0,    0.1,    0x408080c0 },
10419     };
10420
10421     memset(&caps, 0, sizeof(caps));
10422     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10423     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10424     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10425         skip("D3DTOP_DOTPRODUCT3 not supported\n");
10426         return;
10427     }
10428
10429     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10430     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10431
10432     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10433     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10434
10435     /* dp3_x4 r0, diffuse_bias, tfactor_bias
10436      * mov r0.a, diffuse.a
10437      * mov r0, r0.a
10438      *
10439      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10440      * 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
10441      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10442      */
10443     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10444     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10445     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10446     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10447     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10448     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10449     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10450     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10451     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10452     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10453     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10454     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10455     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10456     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10457     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10458     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10459     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10460     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10461
10462     hr = IDirect3DDevice9_BeginScene(device);
10463     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10464     if(SUCCEEDED(hr)) {
10465         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10466         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10467         hr = IDirect3DDevice9_EndScene(device);
10468         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10469     }
10470
10471     color = getPixelColor(device, 320, 240);
10472     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10473        color);
10474     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10475     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10476
10477     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10478     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10479     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10480     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10481     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10482     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10483 }
10484
10485 static void zwriteenable_test(IDirect3DDevice9 *device) {
10486     HRESULT hr;
10487     DWORD color;
10488     struct vertex quad1[] = {
10489         { -1.0,  -1.0,  0.1,    0x00ff0000},
10490         { -1.0,   1.0,  0.1,    0x00ff0000},
10491         {  1.0,  -1.0,  0.1,    0x00ff0000},
10492         {  1.0,   1.0,  0.1,    0x00ff0000},
10493     };
10494     struct vertex quad2[] = {
10495         { -1.0,  -1.0,  0.9,    0x0000ff00},
10496         { -1.0,   1.0,  0.9,    0x0000ff00},
10497         {  1.0,  -1.0,  0.9,    0x0000ff00},
10498         {  1.0,   1.0,  0.9,    0x0000ff00},
10499     };
10500
10501     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10502     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10503
10504     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10505     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10506     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10507     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10508     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10509     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10510     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10511     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10512
10513     hr = IDirect3DDevice9_BeginScene(device);
10514     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10515     if(SUCCEEDED(hr)) {
10516         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10517          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10518          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10519          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10520          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10521          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10522          */
10523         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10524         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10525         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10526         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10527         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10528         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10529
10530         hr = IDirect3DDevice9_EndScene(device);
10531         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10532     }
10533
10534     color = getPixelColor(device, 320, 240);
10535     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10536        color);
10537     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10538     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10539
10540     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10541     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10542 }
10543
10544 static void alphatest_test(IDirect3DDevice9 *device) {
10545 #define ALPHATEST_PASSED 0x0000ff00
10546 #define ALPHATEST_FAILED 0x00ff0000
10547     struct {
10548         D3DCMPFUNC  func;
10549         DWORD       color_less;
10550         DWORD       color_equal;
10551         DWORD       color_greater;
10552     } testdata[] = {
10553         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10554         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10555         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10556         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10557         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10558         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10559         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10560         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10561     };
10562     unsigned int i, j;
10563     HRESULT hr;
10564     DWORD color;
10565     struct vertex quad[] = {
10566         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10567         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10568         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10569         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10570     };
10571     D3DCAPS9 caps;
10572
10573     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10574     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10575     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10576     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10577
10578     for(j = 0; j < 2; j++) {
10579         if(j == 1) {
10580             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10581              * the alpha test either for performance reasons(floating point RTs) or to work
10582              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10583              * codepath for ffp and shader in this case, and the test should cover both
10584              */
10585             IDirect3DPixelShader9 *ps;
10586             DWORD shader_code[] = {
10587                 0xffff0101,                                 /* ps_1_1           */
10588                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10589                 0x0000ffff                                  /* end              */
10590             };
10591             memset(&caps, 0, sizeof(caps));
10592             hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10593             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10594             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10595                 break;
10596             }
10597
10598             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10599             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10600             hr = IDirect3DDevice9_SetPixelShader(device, ps);
10601             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10602             IDirect3DPixelShader9_Release(ps);
10603         }
10604
10605         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10606             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10607             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10608
10609             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10610             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10611             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10612             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10613             hr = IDirect3DDevice9_BeginScene(device);
10614             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10615             if(SUCCEEDED(hr)) {
10616                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10617                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10618                 hr = IDirect3DDevice9_EndScene(device);
10619                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10620             }
10621             color = getPixelColor(device, 320, 240);
10622             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10623             color, testdata[i].color_less, testdata[i].func);
10624             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10625             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10626
10627             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10628             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10629             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10630             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10631             hr = IDirect3DDevice9_BeginScene(device);
10632             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10633             if(SUCCEEDED(hr)) {
10634                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10635                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10636                 hr = IDirect3DDevice9_EndScene(device);
10637                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10638             }
10639             color = getPixelColor(device, 320, 240);
10640             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10641             color, testdata[i].color_equal, testdata[i].func);
10642             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10643             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10644
10645             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10646             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10647             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10648             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10649             hr = IDirect3DDevice9_BeginScene(device);
10650             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10651             if(SUCCEEDED(hr)) {
10652                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10653                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10654                 hr = IDirect3DDevice9_EndScene(device);
10655                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10656             }
10657             color = getPixelColor(device, 320, 240);
10658             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10659             color, testdata[i].color_greater, testdata[i].func);
10660             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10661             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10662         }
10663     }
10664
10665     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10666     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10667     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10668     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10669 }
10670
10671 static void sincos_test(IDirect3DDevice9 *device) {
10672     const DWORD sin_shader_code[] = {
10673         0xfffe0200,                                                                 /* vs_2_0                       */
10674         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10675         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10676         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10677         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10678         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10679         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10680         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10681         0x0000ffff                                                                  /* end                          */
10682     };
10683     const DWORD cos_shader_code[] = {
10684         0xfffe0200,                                                                 /* vs_2_0                       */
10685         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10686         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10687         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10688         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10689         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10690         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10691         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10692         0x0000ffff                                                                  /* end                          */
10693     };
10694     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10695     HRESULT hr;
10696     struct {
10697         float x, y, z;
10698     } data[1280];
10699     unsigned int i;
10700     float sincosc1[4] = {D3DSINCOSCONST1};
10701     float sincosc2[4] = {D3DSINCOSCONST2};
10702
10703     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10704     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10705
10706     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10707     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10708     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10709     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10710     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10711     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10712     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10713     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10714     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10715     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10716
10717     /* Generate a point from -1 to 1 every 0.5 pixels */
10718     for(i = 0; i < 1280; i++) {
10719         data[i].x = (-640.0 + i) / 640.0;
10720         data[i].y = 0.0;
10721         data[i].z = 0.1;
10722     }
10723
10724     hr = IDirect3DDevice9_BeginScene(device);
10725     if(SUCCEEDED(hr)) {
10726         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10727         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10728         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10729         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10730
10731         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10732         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10733         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10734         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10735
10736         hr = IDirect3DDevice9_EndScene(device);
10737         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10738     }
10739     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10740     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10741     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10742
10743     IDirect3DDevice9_SetVertexShader(device, NULL);
10744     IDirect3DVertexShader9_Release(sin_shader);
10745     IDirect3DVertexShader9_Release(cos_shader);
10746 }
10747
10748 static void loop_index_test(IDirect3DDevice9 *device) {
10749     const DWORD shader_code[] = {
10750         0xfffe0200,                                                 /* vs_2_0                   */
10751         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10752         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10753         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10754         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10755         0x0000001d,                                                 /* endloop                  */
10756         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10757         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10758         0x0000ffff                                                  /* END                      */
10759     };
10760     IDirect3DVertexShader9 *shader;
10761     HRESULT hr;
10762     DWORD color;
10763     const float quad[] = {
10764         -1.0,   -1.0,   0.1,
10765          1.0,   -1.0,   0.1,
10766         -1.0,    1.0,   0.1,
10767          1.0,    1.0,   0.1
10768     };
10769     const float zero[4] = {0, 0, 0, 0};
10770     const float one[4] = {1, 1, 1, 1};
10771     int i0[4] = {2, 10, -3, 0};
10772     float values[4];
10773
10774     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10775     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10776     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10777     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10778     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10779     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10780     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10781     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10782
10783     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10784     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10785     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10786     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10787     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10788     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10789     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10790     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10791     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10792     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10793     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10794     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10795     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10796     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10797     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10798     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10799     values[0] = 1.0;
10800     values[1] = 1.0;
10801     values[2] = 0.0;
10802     values[3] = 0.0;
10803     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10804     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10805     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10806     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10807     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10808     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10809     values[0] = -1.0;
10810     values[1] = 0.0;
10811     values[2] = 0.0;
10812     values[3] = 0.0;
10813     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10814     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10815     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10816     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10817     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10818     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10819     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10820     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10821     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10822     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10823
10824     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10825     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10826
10827     hr = IDirect3DDevice9_BeginScene(device);
10828     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10829     if(SUCCEEDED(hr))
10830     {
10831         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10832         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10833         hr = IDirect3DDevice9_EndScene(device);
10834         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10835     }
10836     color = getPixelColor(device, 320, 240);
10837     ok(color_match(color, 0x0000ff00, 1),
10838        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10839     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10840     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10841
10842     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10843     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10844     IDirect3DVertexShader9_Release(shader);
10845 }
10846
10847 static void sgn_test(IDirect3DDevice9 *device) {
10848     const DWORD shader_code[] = {
10849         0xfffe0200,                                                             /* vs_2_0                       */
10850         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10851         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10852         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10853         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10854         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10855         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10856         0x0000ffff                                                              /* end                          */
10857     };
10858     IDirect3DVertexShader9 *shader;
10859     HRESULT hr;
10860     DWORD color;
10861     const float quad[] = {
10862         -1.0,   -1.0,   0.1,
10863          1.0,   -1.0,   0.1,
10864         -1.0,    1.0,   0.1,
10865          1.0,    1.0,   0.1
10866     };
10867
10868     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10869     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10870     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10871     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10872     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10873     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10874     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10875     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10876
10877     hr = IDirect3DDevice9_BeginScene(device);
10878     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10879     if(SUCCEEDED(hr))
10880     {
10881         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10882         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10883         hr = IDirect3DDevice9_EndScene(device);
10884         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10885     }
10886     color = getPixelColor(device, 320, 240);
10887     ok(color_match(color, 0x008000ff, 1),
10888        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10889     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10890     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10891
10892     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10893     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10894     IDirect3DVertexShader9_Release(shader);
10895 }
10896
10897 static void viewport_test(IDirect3DDevice9 *device) {
10898     HRESULT hr;
10899     DWORD color;
10900     D3DVIEWPORT9 vp, old_vp;
10901     BOOL draw_failed = TRUE;
10902     const float quad[] =
10903     {
10904         -0.5,   -0.5,   0.1,
10905          0.5,   -0.5,   0.1,
10906         -0.5,    0.5,   0.1,
10907          0.5,    0.5,   0.1
10908     };
10909
10910     memset(&old_vp, 0, sizeof(old_vp));
10911     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10912     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10913
10914     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10915     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10916
10917     /* Test a viewport with Width and Height bigger than the surface dimensions
10918      *
10919      * TODO: Test Width < surface.width, but X + Width > surface.width
10920      * TODO: Test Width < surface.width, what happens with the height?
10921      *
10922      * The expected behavior is that the viewport behaves like the "default"
10923      * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
10924      * MinZ = 0.0, MaxZ = 1.0.
10925      *
10926      * Starting with Windows 7 the behavior among driver versions is not
10927      * consistent. The SetViewport call is accepted on all drivers. Some
10928      * drivers(older nvidia ones) refuse to draw and return an error. Newer
10929      * nvidia drivers draw, but use the actual values in the viewport and only
10930      * display the upper left part on the surface.
10931      */
10932     memset(&vp, 0, sizeof(vp));
10933     vp.X = 0;
10934     vp.Y = 0;
10935     vp.Width = 10000;
10936     vp.Height = 10000;
10937     vp.MinZ = 0.0;
10938     vp.MaxZ = 0.0;
10939     hr = IDirect3DDevice9_SetViewport(device, &vp);
10940     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10941
10942     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10943     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10944     hr = IDirect3DDevice9_BeginScene(device);
10945     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10946     if(SUCCEEDED(hr))
10947     {
10948         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10949         ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10950         draw_failed = FAILED(hr);
10951         hr = IDirect3DDevice9_EndScene(device);
10952         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10953     }
10954
10955     if(!draw_failed)
10956     {
10957         color = getPixelColor(device, 158, 118);
10958         ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10959         color = getPixelColor(device, 162, 118);
10960         ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10961         color = getPixelColor(device, 158, 122);
10962         ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10963         color = getPixelColor(device, 162, 122);
10964         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
10965
10966         color = getPixelColor(device, 478, 358);
10967         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
10968         color = getPixelColor(device, 482, 358);
10969         ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10970         color = getPixelColor(device, 478, 362);
10971         ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10972         color = getPixelColor(device, 482, 362);
10973         ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10974     }
10975
10976     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10977     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10978
10979     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10980     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10981 }
10982
10983 /* This test tests depth clamping / clipping behaviour:
10984  *   - With software vertex processing, depth values are clamped to the
10985  *     minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
10986  *     when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
10987  *     same as regular vertices here.
10988  *   - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
10989  *     Normal vertices are always clipped. Pretransformed vertices are
10990  *     clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
10991  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10992  */
10993 static void depth_clamp_test(IDirect3DDevice9 *device)
10994 {
10995     const struct tvertex quad1[] =
10996     {
10997         {  0.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
10998         {640.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
10999         {  0.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
11000         {640.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
11001     };
11002     const struct tvertex quad2[] =
11003     {
11004         {  0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
11005         {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
11006         {  0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
11007         {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
11008     };
11009     const struct tvertex quad3[] =
11010     {
11011         {112.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
11012         {208.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
11013         {112.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
11014         {208.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
11015     };
11016     const struct tvertex quad4[] =
11017     {
11018         { 42.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
11019         {112.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
11020         { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
11021         {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
11022     };
11023     const struct vertex quad5[] =
11024     {
11025         { -0.5f,   0.5f, 10.0f,       0xff14f914},
11026         {  0.5f,   0.5f, 10.0f,       0xff14f914},
11027         { -0.5f,  -0.5f, 10.0f,       0xff14f914},
11028         {  0.5f,  -0.5f, 10.0f,       0xff14f914},
11029     };
11030     const struct vertex quad6[] =
11031     {
11032         { -1.0f,   0.5f, 10.0f,      0xfff91414},
11033         {  1.0f,   0.5f, 10.0f,      0xfff91414},
11034         { -1.0f,  0.25f, 10.0f,      0xfff91414},
11035         {  1.0f,  0.25f, 10.0f,      0xfff91414},
11036     };
11037
11038     D3DVIEWPORT9 vp;
11039     D3DCOLOR color;
11040     D3DCAPS9 caps;
11041     HRESULT hr;
11042
11043     vp.X = 0;
11044     vp.Y = 0;
11045     vp.Width = 640;
11046     vp.Height = 480;
11047     vp.MinZ = 0.0;
11048     vp.MaxZ = 7.5;
11049
11050     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11051     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11052
11053     hr = IDirect3DDevice9_SetViewport(device, &vp);
11054     if(FAILED(hr))
11055     {
11056         /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
11057          * the tests because the 7.5 is just intended to show that it doesn't have
11058          * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
11059          * viewport and continue.
11060          */
11061         ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
11062         vp.MaxZ = 1.0;
11063         hr = IDirect3DDevice9_SetViewport(device, &vp);
11064     }
11065     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11066
11067     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
11068     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11069
11070     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
11071     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11072     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11073     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11074     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11075     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11076     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11077     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11078
11079     hr = IDirect3DDevice9_BeginScene(device);
11080     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11081
11082     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11083     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11084
11085     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11086     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11087     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11088     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11089
11090     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11091     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11092
11093     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11094     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11095     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
11096     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11097
11098     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
11099     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11100
11101     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11102     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11103
11104     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
11105     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11106
11107     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11108     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11109
11110     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
11111     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11112
11113     hr = IDirect3DDevice9_EndScene(device);
11114     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11115
11116     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
11117     {
11118         color = getPixelColor(device, 75, 75);
11119         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11120         color = getPixelColor(device, 150, 150);
11121         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11122         color = getPixelColor(device, 320, 240);
11123         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11124         color = getPixelColor(device, 320, 330);
11125         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11126         color = getPixelColor(device, 320, 330);
11127         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11128     }
11129     else
11130     {
11131         color = getPixelColor(device, 75, 75);
11132         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11133         color = getPixelColor(device, 150, 150);
11134         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11135         color = getPixelColor(device, 320, 240);
11136         ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11137         color = getPixelColor(device, 320, 330);
11138         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11139         color = getPixelColor(device, 320, 330);
11140         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11141     }
11142
11143     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11144     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11145
11146     vp.MinZ = 0.0;
11147     vp.MaxZ = 1.0;
11148     hr = IDirect3DDevice9_SetViewport(device, &vp);
11149     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11150 }
11151
11152 static void depth_bounds_test(IDirect3DDevice9 *device)
11153 {
11154     const struct tvertex quad1[] =
11155     {
11156         {    0,    0, 0.0f, 1, 0xfff9e814},
11157         {  640,    0, 0.0f, 1, 0xfff9e814},
11158         {    0,  480, 1.0f, 1, 0xfff9e814},
11159         {  640,  480, 1.0f, 1, 0xfff9e814},
11160     };
11161     const struct tvertex quad2[] =
11162     {
11163         {    0,    0,  0.6f, 1, 0xff002b7f},
11164         {  640,    0,  0.6f, 1, 0xff002b7f},
11165         {    0,  480,  0.6f, 1, 0xff002b7f},
11166         {  640,  480,  0.6f, 1, 0xff002b7f},
11167     };
11168     const struct tvertex quad3[] =
11169     {
11170         {    0,  100, 0.6f, 1, 0xfff91414},
11171         {  640,  100, 0.6f, 1, 0xfff91414},
11172         {    0,  160, 0.6f, 1, 0xfff91414},
11173         {  640,  160, 0.6f, 1, 0xfff91414},
11174     };
11175
11176     union {
11177         DWORD d;
11178         float f;
11179     } tmpvalue;
11180
11181     IDirect3D9 *d3d = NULL;
11182     IDirect3DSurface9 *offscreen_surface = NULL;
11183     D3DCOLOR color;
11184     HRESULT hr;
11185
11186     IDirect3DDevice9_GetDirect3D(device, &d3d);
11187     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11188             0,  D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
11189         skip("No NVDB (depth bounds test) support\n");
11190         IDirect3D9_Release(d3d);
11191         return;
11192     }
11193     IDirect3D9_Release(d3d);
11194
11195     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
11196             MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
11197     ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
11198     if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
11199
11200     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
11201     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11202
11203     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11204     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11205     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
11206     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11207     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11208     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11209     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11210     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11211
11212
11213     hr = IDirect3DDevice9_BeginScene(device);
11214     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11215
11216     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11217     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11218
11219     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11220     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11221
11222     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
11223     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11224
11225     tmpvalue.f = 0.625;
11226     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11227     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11228
11229     tmpvalue.f = 0.75;
11230     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
11231     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11232
11233     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11234     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11235
11236     tmpvalue.f = 0.75;
11237     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11238     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11239
11240     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11241     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11242
11243     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
11244     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11245
11246     hr = IDirect3DDevice9_EndScene(device);
11247     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11248
11249     color = getPixelColor(device, 150, 130);
11250     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11251     color = getPixelColor(device, 150, 200);
11252     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11253     color = getPixelColor(device, 150, 300-5);
11254     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11255     color = getPixelColor(device, 150, 300+5);
11256     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11257     color = getPixelColor(device, 150, 330);
11258     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11259     color = getPixelColor(device, 150, 360-5);
11260     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11261     color = getPixelColor(device, 150, 360+5);
11262     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11263
11264     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11265     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11266 }
11267
11268 static void depth_buffer_test(IDirect3DDevice9 *device)
11269 {
11270     static const struct vertex quad1[] =
11271     {
11272         { -1.0,  1.0, 0.33f, 0xff00ff00},
11273         {  1.0,  1.0, 0.33f, 0xff00ff00},
11274         { -1.0, -1.0, 0.33f, 0xff00ff00},
11275         {  1.0, -1.0, 0.33f, 0xff00ff00},
11276     };
11277     static const struct vertex quad2[] =
11278     {
11279         { -1.0,  1.0, 0.50f, 0xffff00ff},
11280         {  1.0,  1.0, 0.50f, 0xffff00ff},
11281         { -1.0, -1.0, 0.50f, 0xffff00ff},
11282         {  1.0, -1.0, 0.50f, 0xffff00ff},
11283     };
11284     static const struct vertex quad3[] =
11285     {
11286         { -1.0,  1.0, 0.66f, 0xffff0000},
11287         {  1.0,  1.0, 0.66f, 0xffff0000},
11288         { -1.0, -1.0, 0.66f, 0xffff0000},
11289         {  1.0, -1.0, 0.66f, 0xffff0000},
11290     };
11291     static const DWORD expected_colors[4][4] =
11292     {
11293         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11294         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11295         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11296         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11297     };
11298
11299     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
11300     unsigned int i, j;
11301     D3DVIEWPORT9 vp;
11302     D3DCOLOR color;
11303     HRESULT hr;
11304
11305     vp.X = 0;
11306     vp.Y = 0;
11307     vp.Width = 640;
11308     vp.Height = 480;
11309     vp.MinZ = 0.0;
11310     vp.MaxZ = 1.0;
11311
11312     hr = IDirect3DDevice9_SetViewport(device, &vp);
11313     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11314
11315     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11316     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11317     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11318     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11319     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11320     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11321     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11322     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11323     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11324     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11325
11326     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11327     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11328     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
11329             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11330     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11331     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11332             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11333     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11334     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11335             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
11336     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11337
11338     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11339     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11340     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11341     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11342
11343     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11344     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11345     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11346     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11347
11348     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11349     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11350     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11351     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11352
11353     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11354     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11355     hr = IDirect3DDevice9_BeginScene(device);
11356     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11357     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11358     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11359     hr = IDirect3DDevice9_EndScene(device);
11360     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11361
11362     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11363     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11364
11365     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11366     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11367
11368     hr = IDirect3DDevice9_BeginScene(device);
11369     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11370     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11371     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11372     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11373     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11374     hr = IDirect3DDevice9_EndScene(device);
11375     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11376
11377     for (i = 0; i < 4; ++i)
11378     {
11379         for (j = 0; j < 4; ++j)
11380         {
11381             unsigned int x = 80 * ((2 * j) + 1);
11382             unsigned int y = 60 * ((2 * i) + 1);
11383             color = getPixelColor(device, x, y);
11384             ok(color_match(color, expected_colors[i][j], 0),
11385                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11386         }
11387     }
11388
11389     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11390     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11391
11392     IDirect3DSurface9_Release(backbuffer);
11393     IDirect3DSurface9_Release(rt3);
11394     IDirect3DSurface9_Release(rt2);
11395     IDirect3DSurface9_Release(rt1);
11396 }
11397
11398 /* Test that partial depth copies work the way they're supposed to. The clear
11399  * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
11400  * the following draw should only copy back the part that was modified. */
11401 static void depth_buffer2_test(IDirect3DDevice9 *device)
11402 {
11403     static const struct vertex quad[] =
11404     {
11405         { -1.0,  1.0, 0.66f, 0xffff0000},
11406         {  1.0,  1.0, 0.66f, 0xffff0000},
11407         { -1.0, -1.0, 0.66f, 0xffff0000},
11408         {  1.0, -1.0, 0.66f, 0xffff0000},
11409     };
11410
11411     IDirect3DSurface9 *backbuffer, *rt1, *rt2;
11412     unsigned int i, j;
11413     D3DVIEWPORT9 vp;
11414     D3DCOLOR color;
11415     HRESULT hr;
11416
11417     vp.X = 0;
11418     vp.Y = 0;
11419     vp.Width = 640;
11420     vp.Height = 480;
11421     vp.MinZ = 0.0;
11422     vp.MaxZ = 1.0;
11423
11424     hr = IDirect3DDevice9_SetViewport(device, &vp);
11425     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11426
11427     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11428     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11429     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11430     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11431     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11432     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11433     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11434     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11435     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11436     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11437
11438     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11439             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11440     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11441     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11442             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11443     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11444     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11445     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11446
11447     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11448     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11449     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11450     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11451
11452     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11453     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11454     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
11455     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11456
11457     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11458     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11459     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11460     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11461
11462     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11463     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11464
11465     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11466     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11467
11468     hr = IDirect3DDevice9_BeginScene(device);
11469     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11470     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11471     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11472     hr = IDirect3DDevice9_EndScene(device);
11473     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11474
11475     for (i = 0; i < 4; ++i)
11476     {
11477         for (j = 0; j < 4; ++j)
11478         {
11479             unsigned int x = 80 * ((2 * j) + 1);
11480             unsigned int y = 60 * ((2 * i) + 1);
11481             color = getPixelColor(device, x, y);
11482             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11483                     "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
11484         }
11485     }
11486
11487     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11488     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11489
11490     IDirect3DSurface9_Release(backbuffer);
11491     IDirect3DSurface9_Release(rt2);
11492     IDirect3DSurface9_Release(rt1);
11493 }
11494
11495 static void depth_blit_test(IDirect3DDevice9 *device)
11496 {
11497     static const struct vertex quad1[] =
11498     {
11499         { -1.0,  1.0, 0.50f, 0xff00ff00},
11500         {  1.0,  1.0, 0.50f, 0xff00ff00},
11501         { -1.0, -1.0, 0.50f, 0xff00ff00},
11502         {  1.0, -1.0, 0.50f, 0xff00ff00},
11503     };
11504     static const struct vertex quad2[] =
11505     {
11506         { -1.0,  1.0, 0.66f, 0xff0000ff},
11507         {  1.0,  1.0, 0.66f, 0xff0000ff},
11508         { -1.0, -1.0, 0.66f, 0xff0000ff},
11509         {  1.0, -1.0, 0.66f, 0xff0000ff},
11510     };
11511     static const DWORD expected_colors[4][4] =
11512     {
11513         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11514         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11515         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11516         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11517     };
11518
11519     IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
11520     RECT src_rect, dst_rect;
11521     unsigned int i, j;
11522     D3DVIEWPORT9 vp;
11523     D3DCOLOR color;
11524     HRESULT hr;
11525
11526     vp.X = 0;
11527     vp.Y = 0;
11528     vp.Width = 640;
11529     vp.Height = 480;
11530     vp.MinZ = 0.0;
11531     vp.MaxZ = 1.0;
11532
11533     hr = IDirect3DDevice9_SetViewport(device, &vp);
11534     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11535
11536     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11537     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11538     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11539     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11540     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11541     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11542     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11543     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11544     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
11545     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11546
11547     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11548     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11549     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11550     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11551     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11552     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11553     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11554     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11555
11556     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11557     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11558     SetRect(&dst_rect, 0, 0, 480, 360);
11559     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11560     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11561     SetRect(&dst_rect, 0, 0, 320, 240);
11562     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11563     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11564
11565     /* Partial blit. */
11566     SetRect(&src_rect, 0, 0, 320, 240);
11567     SetRect(&dst_rect, 0, 0, 320, 240);
11568     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11569     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11570     /* Flipped. */
11571     SetRect(&src_rect, 0, 0, 640, 480);
11572     SetRect(&dst_rect, 0, 480, 640, 0);
11573     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11574     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11575     /* Full, explicit. */
11576     SetRect(&src_rect, 0, 0, 640, 480);
11577     SetRect(&dst_rect, 0, 0, 640, 480);
11578     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11579     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11580     /* Filtered blit. */
11581     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11582     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11583     /* Depth -> color blit.*/
11584     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11585     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11586     IDirect3DSurface9_Release(backbuffer);
11587     /* Full surface, different sizes */
11588     hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
11589     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11590     hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
11591     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11592
11593     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11594     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11595     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11596     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11597     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11598     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11599
11600     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11601     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11602     hr = IDirect3DDevice9_BeginScene(device);
11603     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11604     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11605     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11606     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11607     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11608     hr = IDirect3DDevice9_EndScene(device);
11609     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11610
11611     for (i = 0; i < 4; ++i)
11612     {
11613         for (j = 0; j < 4; ++j)
11614         {
11615             unsigned int x = 80 * ((2 * j) + 1);
11616             unsigned int y = 60 * ((2 * i) + 1);
11617             color = getPixelColor(device, x, y);
11618             ok(color_match(color, expected_colors[i][j], 0),
11619                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11620         }
11621     }
11622
11623     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11624     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11625
11626     IDirect3DSurface9_Release(ds3);
11627     IDirect3DSurface9_Release(ds2);
11628     IDirect3DSurface9_Release(ds1);
11629 }
11630
11631 static void intz_test(IDirect3DDevice9 *device)
11632 {
11633     static const DWORD ps_code[] =
11634     {
11635         0xffff0200,                                                             /* ps_2_0                       */
11636         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11637         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11638         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11639         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11640         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11641         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11642         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11643         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11644         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
11645         0x0000ffff,                                                             /* end                          */
11646     };
11647     struct
11648     {
11649         float x, y, z;
11650         float s, t, p, q;
11651     }
11652     quad[] =
11653     {
11654         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11655         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11656         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11657         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11658     },
11659     half_quad_1[] =
11660     {
11661         { -1.0f,  0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11662         {  1.0f,  0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11663         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11664         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11665     },
11666     half_quad_2[] =
11667     {
11668         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11669         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11670         { -1.0f,  0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11671         {  1.0f,  0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11672     };
11673     struct
11674     {
11675         UINT x, y;
11676         D3DCOLOR color;
11677     }
11678     expected_colors[] =
11679     {
11680         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11681         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11682         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11683         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11684         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11685         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11686         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11687         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11688     };
11689
11690     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11691     IDirect3DTexture9 *texture;
11692     IDirect3DPixelShader9 *ps;
11693     IDirect3DSurface9 *ds;
11694     IDirect3D9 *d3d9;
11695     D3DCAPS9 caps;
11696     HRESULT hr;
11697     UINT i;
11698
11699     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11700     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11701     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11702     {
11703         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11704         return;
11705     }
11706     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
11707     {
11708         skip("No unconditional NP2 texture support, skipping INTZ test.\n");
11709         return;
11710     }
11711
11712     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11713     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11714
11715     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11716             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11717     if (FAILED(hr))
11718     {
11719         skip("No INTZ support, skipping INTZ test.\n");
11720         return;
11721     }
11722
11723     IDirect3D9_Release(d3d9);
11724
11725     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11726     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11727     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11728     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11729
11730     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11731             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11732     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11733     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11734             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11735     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11736     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11737     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11738
11739     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11740     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11741     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11742     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11743     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11744     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11745     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11746     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11747     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11748     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11749
11750     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11751     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11752     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11753     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11754     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11755     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11756     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11757     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11758     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11759     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11760
11761     /* Render offscreen, using the INTZ texture as depth buffer */
11762     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11763     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11764     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11765     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11766     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11767     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11768     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11769     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11770
11771     /* Setup the depth/stencil surface. */
11772     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11773     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11774
11775     hr = IDirect3DDevice9_BeginScene(device);
11776     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11777     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11778     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11779     hr = IDirect3DDevice9_EndScene(device);
11780     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11781
11782     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11783     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11784     IDirect3DSurface9_Release(ds);
11785     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11786     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11787     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11788     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11789     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11790     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11791
11792     /* Read the depth values back. */
11793     hr = IDirect3DDevice9_BeginScene(device);
11794     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11795     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11796     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11797     hr = IDirect3DDevice9_EndScene(device);
11798     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11799
11800     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11801     {
11802         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11803         ok(color_match(color, expected_colors[i].color, 1),
11804                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11805                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11806     }
11807
11808     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11809     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11810
11811     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11812     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11813     IDirect3DTexture9_Release(texture);
11814
11815     /* Render onscreen while using the INTZ texture as depth buffer */
11816     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11817             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11818     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11819     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11820     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11821     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11822     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11823     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11824
11825     /* Setup the depth/stencil surface. */
11826     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11827     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11828
11829     hr = IDirect3DDevice9_BeginScene(device);
11830     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11831     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11832     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11833     hr = IDirect3DDevice9_EndScene(device);
11834     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11835
11836     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11837     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11838     IDirect3DSurface9_Release(ds);
11839     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11840     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11841     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11842     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11843
11844     /* Read the depth values back. */
11845     hr = IDirect3DDevice9_BeginScene(device);
11846     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11847     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11848     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11849     hr = IDirect3DDevice9_EndScene(device);
11850     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11851
11852     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11853     {
11854         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11855         ok(color_match(color, expected_colors[i].color, 1),
11856                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11857                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11858     }
11859
11860     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11861     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11862
11863     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11864     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11865     IDirect3DTexture9_Release(texture);
11866
11867     /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
11868     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11869             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11870     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11871     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11872
11873     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11874     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11875     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11876     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11877     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11878     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11879
11880     /* Setup the depth/stencil surface. */
11881     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11882     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11883
11884     hr = IDirect3DDevice9_BeginScene(device);
11885     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11886     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
11887     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11888     hr = IDirect3DDevice9_EndScene(device);
11889     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11890
11891     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11892     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11893
11894     hr = IDirect3DDevice9_BeginScene(device);
11895     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11896     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
11897     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11898     hr = IDirect3DDevice9_EndScene(device);
11899     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11900
11901     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11902     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11903     IDirect3DSurface9_Release(ds);
11904     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11905     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11906     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11907     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11908
11909     /* Read the depth values back. */
11910     hr = IDirect3DDevice9_BeginScene(device);
11911     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11912     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11913     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11914     hr = IDirect3DDevice9_EndScene(device);
11915     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11916
11917     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11918     {
11919         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11920         ok(color_match(color, expected_colors[i].color, 1),
11921                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11922                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11923     }
11924
11925     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11926     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11927
11928     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11929     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11930     IDirect3DSurface9_Release(original_ds);
11931     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11932     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11933     IDirect3DTexture9_Release(texture);
11934     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11935     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11936     IDirect3DPixelShader9_Release(ps);
11937
11938     IDirect3DSurface9_Release(original_rt);
11939     IDirect3DSurface9_Release(rt);
11940 }
11941
11942 static void shadow_test(IDirect3DDevice9 *device)
11943 {
11944     static const DWORD ps_code[] =
11945     {
11946         0xffff0200,                                                             /* ps_2_0                       */
11947         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11948         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11949         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11950         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11951         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11952         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11953         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11954         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11955         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11956         0x0000ffff,                                                             /* end                          */
11957     };
11958     struct
11959     {
11960         D3DFORMAT format;
11961         const char *name;
11962     }
11963     formats[] =
11964     {
11965         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
11966         {D3DFMT_D32,            "D3DFMT_D32"},
11967         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
11968         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
11969         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
11970         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
11971         {D3DFMT_D16,            "D3DFMT_D16"},
11972         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
11973         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
11974     };
11975     struct
11976     {
11977         float x, y, z;
11978         float s, t, p, q;
11979     }
11980     quad[] =
11981     {
11982         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11983         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11984         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11985         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11986     };
11987     struct
11988     {
11989         UINT x, y;
11990         D3DCOLOR color;
11991     }
11992     expected_colors[] =
11993     {
11994         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11995         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11996         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11997         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11998         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11999         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12000         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12001         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12002     };
12003
12004     IDirect3DSurface9 *original_ds, *original_rt, *rt;
12005     IDirect3DPixelShader9 *ps;
12006     IDirect3D9 *d3d9;
12007     D3DCAPS9 caps;
12008     HRESULT hr;
12009     UINT i;
12010
12011     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12012     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12013     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
12014     {
12015         skip("No pixel shader 2.0 support, skipping shadow test.\n");
12016         return;
12017     }
12018
12019     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
12020     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12021     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12022     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12023     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
12024     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
12025
12026     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
12027             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12028     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12029     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12030     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12031
12032     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
12033     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12034     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12035     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12036     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
12037     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12038     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12039     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12040     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12041     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12042
12043     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
12044     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12045     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
12046     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12047     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
12048     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12049     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
12050     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12051     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12052     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12053
12054     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
12055     {
12056         D3DFORMAT format = formats[i].format;
12057         IDirect3DTexture9 *texture;
12058         IDirect3DSurface9 *ds;
12059         unsigned int j;
12060
12061         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12062                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
12063         if (FAILED(hr)) continue;
12064
12065         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
12066                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
12067         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12068
12069         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
12070         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12071
12072         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12073         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12074
12075         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12076         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12077
12078         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12079         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12080
12081         /* Setup the depth/stencil surface. */
12082         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
12083         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12084
12085         hr = IDirect3DDevice9_BeginScene(device);
12086         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12087         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12088         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12089         hr = IDirect3DDevice9_EndScene(device);
12090         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12091
12092         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
12093         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12094         IDirect3DSurface9_Release(ds);
12095
12096         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12097         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12098
12099         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12100         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12101
12102         hr = IDirect3DDevice9_SetPixelShader(device, ps);
12103         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12104
12105         /* Do the actual shadow mapping. */
12106         hr = IDirect3DDevice9_BeginScene(device);
12107         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12108         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12109         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12110         hr = IDirect3DDevice9_EndScene(device);
12111         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12112
12113         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12114         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12115         IDirect3DTexture9_Release(texture);
12116
12117         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
12118         {
12119             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
12120             ok(color_match(color, expected_colors[j].color, 0),
12121                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
12122                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
12123                     formats[i].name, color);
12124         }
12125
12126         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12127         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12128     }
12129
12130     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12131     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12132     IDirect3DPixelShader9_Release(ps);
12133
12134     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
12135     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12136     IDirect3DSurface9_Release(original_ds);
12137
12138     IDirect3DSurface9_Release(original_rt);
12139     IDirect3DSurface9_Release(rt);
12140
12141     IDirect3D9_Release(d3d9);
12142 }
12143
12144 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
12145 {
12146     const struct vertex quad1[] =
12147     {
12148         {-1.0f, -1.0f, 0.0f, 0xfff9e814},
12149         { 1.0f, -1.0f, 0.0f, 0xfff9e814},
12150         {-1.0f,  1.0f, 0.0f, 0xfff9e814},
12151         { 1.0f,  1.0f, 0.0f, 0xfff9e814},
12152     };
12153     const struct vertex quad2[] =
12154     {
12155         {-1.0f, -1.0f, 0.0f, 0xff002b7f},
12156         { 1.0f, -1.0f, 0.0f, 0xff002b7f},
12157         {-1.0f,  1.0f, 0.0f, 0xff002b7f},
12158         { 1.0f,  1.0f, 0.0f, 0xff002b7f},
12159     };
12160     D3DCOLOR color;
12161     HRESULT hr;
12162
12163     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
12164     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12165
12166     hr = IDirect3DDevice9_BeginScene(device);
12167     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12168
12169     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12170     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12171
12172     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12173     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12174     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12175     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12176
12177     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
12178     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12179     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12180     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12181
12182     hr = IDirect3DDevice9_EndScene(device);
12183     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12184
12185     color = getPixelColor(device, 1, 240);
12186     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12187     color = getPixelColor(device, 638, 240);
12188     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12189
12190     color = getPixelColor(device, 1, 241);
12191     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12192     color = getPixelColor(device, 638, 241);
12193     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12194 }
12195
12196 static void clip_planes_test(IDirect3DDevice9 *device)
12197 {
12198     const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
12199
12200     const DWORD shader_code[] = {
12201         0xfffe0200, /* vs_2_0 */
12202         0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12203         0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
12204         0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12205         0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
12206         0x0000ffff /* end */
12207     };
12208     IDirect3DVertexShader9 *shader;
12209
12210     IDirect3DTexture9 *offscreen = NULL;
12211     IDirect3DSurface9 *offscreen_surface, *original_rt;
12212     HRESULT hr;
12213
12214     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12215     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12216
12217     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12218     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12219     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12220     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12221     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12222     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12223     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
12224     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12225
12226     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12227     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12228     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12229     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
12230
12231     IDirect3DDevice9_SetClipPlane(device, 0, plane0);
12232
12233     clip_planes(device, "Onscreen FFP");
12234
12235     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
12236     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12237     hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
12238     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12239     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12240     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12241
12242     clip_planes(device, "Offscreen FFP");
12243
12244     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12245     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12246
12247     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12248     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
12249     hr = IDirect3DDevice9_SetVertexShader(device, shader);
12250     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
12251
12252     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12253     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12254
12255     clip_planes(device, "Onscreen vertex shader");
12256
12257     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12258     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12259
12260     clip_planes(device, "Offscreen vertex shader");
12261
12262     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12263     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12264
12265     IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12266     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12267     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12268     IDirect3DVertexShader9_Release(shader);
12269     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12270     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12271     IDirect3DSurface9_Release(original_rt);
12272     IDirect3DSurface9_Release(offscreen_surface);
12273     IDirect3DTexture9_Release(offscreen);
12274 }
12275
12276 static void fp_special_test(IDirect3DDevice9 *device)
12277 {
12278     static const DWORD vs_header[] =
12279     {
12280         0xfffe0200,                                                             /* vs_2_0                       */
12281         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
12282         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
12283         0x0200001f, 0x80000005, 0x900f0001,                                     /* dcl_texcoord0 v1             */
12284     };
12285
12286     static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001};         /* log r0.x, v1.x               */
12287     static const DWORD vs_pow[] =
12288             {0x03000020, 0x80010000, 0x90000001, 0x90000001};                   /* pow r0.x, v1.x, v1.x         */
12289     static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001};         /* nrm r0.xyz, v1.x             */
12290     static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001};        /* rcp r0.x, v1.x               */
12291     static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001};        /* rcp r0.x, -v1.x              */
12292     static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001};        /* rsq r0.x, v1.x               */
12293     static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001};        /* rsq r0.x, -v1.x              */
12294     static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001,          /* lit r0, v1.xxxx              */
12295             0x02000001, 0x80010000, 0x80aa0000};                                /* mov r0.x, v0.z               */
12296
12297     static const DWORD vs_footer[] =
12298     {
12299         0x03000005, 0x80020000, 0x80000000, 0xa0ff0000,                         /* mul r0.y, r0.x, c0.w         */
12300         0x0300000d, 0x80040000, 0x80000000, 0x80550000,                         /* sge r0.z, r0.x, r0.y         */
12301         0x0300000d, 0x80020000, 0x80e40000, 0x80000000,                         /* sge r0.y, r0, r0.x           */
12302         0x03000005, 0x80040000, 0x80550000, 0x80e40000,                         /* mul r0.z, r0.y, r0           */
12303         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
12304         0x0300000c, 0x80020000, 0x80000000, 0x80000000,                         /* slt r0.y, r0.x, r0.x         */
12305         0x03000002, 0x80040000, 0x80550000, 0x80550000,                         /* add r0.z, r0.y, r0.y         */
12306         0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000,                         /* slt r0.y, c0.x, r0.w         */
12307         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
12308         0x03000002, 0x80040000, 0x81550000, 0xa0e40000,                         /* add r0.z, -r0.y, c0          */
12309         0x0300000c, 0x80080000, 0xa0000000, 0x80e40000,                         /* slt r0.w, c0.x, r0           */
12310         0x03000005, 0x80040000, 0x80ff0000, 0x80e40000,                         /* mul r0.z, r0.w, r0           */
12311         0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000,             /* mad r0.y, r0.z, c0, r0       */
12312         0x02000001, 0xe0030000, 0x80e40000,                                     /* mov oT0.xy, r0               */
12313         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
12314         0x0000ffff,                                                             /* end                          */
12315     };
12316
12317     static const struct
12318     {
12319         const char *name;
12320         const DWORD *ops;
12321         DWORD size;
12322         D3DCOLOR r600;
12323         D3DCOLOR nv40;
12324         D3DCOLOR nv50;
12325     }
12326     vs_body[] =
12327     {
12328         /* The basic ideas here are:
12329          *     2.0 * +/-INF == +/-INF
12330          *     NAN != NAN
12331          *
12332          * The vertex shader value is written to the red component, with 0.0
12333          * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
12334          * result in 0x00. The pixel shader value is written to the green
12335          * component, but here 0.0 also results in 0x00. The actual value is
12336          * written to the blue component.
12337          *
12338          * There are considerable differences between graphics cards in how
12339          * these are handled, but pow and nrm never generate INF or NAN. */
12340         {"log",     vs_log,     sizeof(vs_log),     0x00000000, 0x00ff0000, 0x00ff7f00},
12341         {"pow",     vs_pow,     sizeof(vs_pow),     0x000000ff, 0x0000ff00, 0x000000ff},
12342         {"nrm",     vs_nrm,     sizeof(vs_nrm),     0x00ff0000, 0x0000ff00, 0x00ff0000},
12343         {"rcp1",    vs_rcp1,    sizeof(vs_rcp1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12344         {"rcp2",    vs_rcp2,    sizeof(vs_rcp2),    0x00000000, 0x00ff0000, 0x00ff7f00},
12345         {"rsq1",    vs_rsq1,    sizeof(vs_rsq1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12346         {"rsq2",    vs_rsq2,    sizeof(vs_rsq2),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12347         {"lit",     vs_lit,     sizeof(vs_lit),     0x00ff0000, 0x00ff0000, 0x00ff0000},
12348     };
12349
12350     static const DWORD ps_code[] =
12351     {
12352         0xffff0200,                                                             /* ps_2_0                       */
12353         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
12354         0x0200001f, 0x80000000, 0xb0030000,                                     /* dcl t0.xy                    */
12355         0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000,                         /* max r1.x, t0, c0             */
12356         0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000,                         /* min r0.x, t0, c0             */
12357         0x03000002, 0x80010000, 0x80e40000, 0x81e40001,                         /* add r0.x, r0, -r1            */
12358         0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000,             /* mad r1.x, t0, c0.w. -t0      */
12359         0x02000023, 0x80010002, 0x80e40001,                                     /* abs r2.x, r1                 */
12360         0x02000023, 0x80010000, 0x80e40000,                                     /* abs r0.x, r0                 */
12361         0x02000023, 0x80010001, 0xb0e40000,                                     /* abs r1.x, t0                 */
12362         0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r2, c0.z, c0      */
12363         0x02000023, 0x80010002, 0x80e40002,                                     /* abs r2.x, r2                 */
12364         0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r1.x, -r1, c0.z, c0      */
12365         0x02000023, 0x80010001, 0x80e40001,                                     /* abs r1.x, r1                 */
12366         0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r3.x, -r2, c0.z, c0      */
12367         0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r1, c0.z, c0      */
12368         0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000,             /* cmp r0.x, -r0, c0.y, c0      */
12369         0x03000005, 0x80010002, 0x80e40002, 0x80e40003,                         /* mul r2.x, r2, r3             */
12370         0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000,             /* cmp r0.x, -r2, c0.z, r0      */
12371         0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000,             /* cmp r0.y, -r1.x, r0.x, c0.x  */
12372         0x02000001, 0x80050000, 0xb0c90000,                                     /* mov r0.xz, t0.yzxw           */
12373         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.w, c0.z               */
12374         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
12375         0x0000ffff,                                                             /* end                          */
12376     };
12377
12378     struct
12379     {
12380         float x, y, z;
12381         float s;
12382     }
12383     quad[] =
12384     {
12385         { -1.0f,  1.0f, 0.0f, 0.0f},
12386         {  1.0f,  1.0f, 1.0f, 0.0f},
12387         { -1.0f, -1.0f, 0.0f, 0.0f},
12388         {  1.0f, -1.0f, 1.0f, 0.0f},
12389     };
12390
12391     IDirect3DPixelShader9 *ps;
12392     UINT body_size = 0;
12393     DWORD *vs_code;
12394     D3DCAPS9 caps;
12395     HRESULT hr;
12396     UINT i;
12397
12398     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12399     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12400     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12401     {
12402         skip("No shader model 2.0 support, skipping floating point specials test.\n");
12403         return;
12404     }
12405
12406     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
12407     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12408
12409     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12410     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12411     hr = IDirect3DDevice9_SetPixelShader(device, ps);
12412     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12413
12414     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12415     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12416
12417     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
12418     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12419
12420     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12421     {
12422         if (vs_body[i].size > body_size) body_size = vs_body[i].size;
12423     }
12424
12425     vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
12426     memcpy(vs_code, vs_header, sizeof(vs_header));
12427
12428     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12429     {
12430         DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
12431         IDirect3DVertexShader9 *vs;
12432         D3DCOLOR color;
12433
12434         memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
12435         offset += vs_body[i].size / sizeof(*vs_body[i].ops);
12436         memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
12437
12438         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
12439         ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
12440         hr = IDirect3DDevice9_SetVertexShader(device, vs);
12441         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12442
12443         hr = IDirect3DDevice9_BeginScene(device);
12444         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12445         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12446         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12447         hr = IDirect3DDevice9_EndScene(device);
12448         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12449
12450         color = getPixelColor(device, 320, 240);
12451         ok(color_match(color, vs_body[i].r600, 1)
12452                 || color_match(color, vs_body[i].nv40, 1)
12453                 || color_match(color, vs_body[i].nv50, 1),
12454                 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
12455                 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
12456
12457         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12458         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12459
12460         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12461         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12462         IDirect3DVertexShader9_Release(vs);
12463     }
12464
12465     HeapFree(GetProcessHeap(), 0, vs_code);
12466
12467     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12468     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12469     IDirect3DPixelShader9_Release(ps);
12470 }
12471
12472 static void srgbwrite_format_test(IDirect3DDevice9 *device)
12473 {
12474     IDirect3D9 *d3d;
12475     IDirect3DSurface9 *rt, *backbuffer;
12476     IDirect3DTexture9 *texture;
12477     HRESULT hr;
12478     int i;
12479     DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
12480     static const struct
12481     {
12482         D3DFORMAT fmt;
12483         const char *name;
12484     }
12485     formats[] =
12486     {
12487         { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
12488         { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
12489         { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
12490         { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
12491         { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
12492     };
12493     static const struct
12494     {
12495         float x, y, z;
12496         float u, v;
12497     }
12498     quad[] =
12499     {
12500         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12501         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12502         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12503         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12504     };
12505
12506     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12507     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12508     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12509     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12510     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
12511     ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
12512     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12513     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12514     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12515     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12516
12517     for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
12518     {
12519         if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12520                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
12521         {
12522             skip("Format %s not supported as render target, skipping test.\n",
12523                     formats[i].name);
12524             continue;
12525         }
12526
12527         hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
12528                                             D3DPOOL_DEFAULT, &texture, NULL);
12529         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12530         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
12531         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12532
12533         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
12534         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12535         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12536         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12537         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
12538         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12539
12540         hr = IDirect3DDevice9_BeginScene(device);
12541         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12542         if(SUCCEEDED(hr))
12543         {
12544             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
12545             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12546             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
12547             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12548             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12549             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12550
12551             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
12552             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12553             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12554             ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12555             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
12556             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12557             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12558             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12559             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12560             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12561             hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12562             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12563
12564             hr = IDirect3DDevice9_EndScene(device);
12565             ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12566         }
12567
12568         IDirect3DSurface9_Release(rt);
12569         IDirect3DTexture9_Release(texture);
12570
12571         color = getPixelColor(device, 360, 240);
12572         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12573                                     D3DUSAGE_QUERY_SRGBWRITE,
12574                                     D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
12575         {
12576             /* Big slop for R5G6B5 */
12577             ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
12578                 formats[i].name, color_srgb, color);
12579         }
12580         else
12581         {
12582             /* Big slop for R5G6B5 */
12583             ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
12584                 formats[i].name, color_rgb, color);
12585         }
12586
12587         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12588         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12589     }
12590
12591     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12592     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12593
12594     IDirect3D9_Release(d3d);
12595     IDirect3DSurface9_Release(backbuffer);
12596 }
12597
12598 static void ds_size_test(IDirect3DDevice9 *device)
12599 {
12600     IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
12601     HRESULT hr;
12602     DWORD num_passes;
12603     struct
12604     {
12605         float x, y, z;
12606     }
12607     quad[] =
12608     {
12609         {-1.0,  -1.0,   0.0 },
12610         {-1.0,   1.0,   0.0 },
12611         { 1.0,  -1.0,   0.0 },
12612         { 1.0,   1.0,   0.0 }
12613     };
12614
12615     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12616     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12617     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
12618     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
12619     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
12620     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
12621
12622     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12623     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12624     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
12625     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12626     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12627     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12628     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12629     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12630     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12631     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12632     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
12633     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
12634     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12635     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12636     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12637     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12638     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12639     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12640
12641     /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
12642      * but does not change the surface's contents. */
12643     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
12644     ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
12645     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
12646     ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
12647     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
12648     ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12649
12650     /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
12651
12652     /* Turning on any depth-related state results in a ValidateDevice failure */
12653     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12654     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12655     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12656     ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12657         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12658     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12659     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12660     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12661     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12662     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12663     ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12664         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12665
12666     /* Try to draw with the device in an invalid state */
12667     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12668     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12669     hr = IDirect3DDevice9_BeginScene(device);
12670     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12671     if(SUCCEEDED(hr))
12672     {
12673         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12674         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12675         hr = IDirect3DDevice9_EndScene(device);
12676         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12677
12678         /* Don't check the resulting draw unless we find an app that needs it. On nvidia ValidateDevice
12679          * returns CONFLICTINGRENDERSTATE, so the result is undefined. On AMD d3d seems to assume the
12680          * stored Z buffer value is 0.0 for all pixels, even those that are covered by the depth buffer */
12681     }
12682
12683     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12684     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12685     hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12686     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12687     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12688     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12689
12690     IDirect3DSurface9_Release(readback);
12691     IDirect3DSurface9_Release(ds);
12692     IDirect3DSurface9_Release(rt);
12693     IDirect3DSurface9_Release(old_rt);
12694     IDirect3DSurface9_Release(old_ds);
12695 }
12696
12697 static void unbound_sampler_test(IDirect3DDevice9 *device)
12698 {
12699     HRESULT hr;
12700     IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
12701     IDirect3DSurface9 *rt, *old_rt;
12702     DWORD color;
12703
12704     static const DWORD ps_code[] =
12705     {
12706         0xffff0200,                                     /* ps_2_0           */
12707         0x0200001f, 0x90000000, 0xa00f0800,             /* dcl_2d s0        */
12708         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12709         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12710         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12711         0x0000ffff,                                     /* end              */
12712     };
12713     static const DWORD ps_code_cube[] =
12714     {
12715         0xffff0200,                                     /* ps_2_0           */
12716         0x0200001f, 0x98000000, 0xa00f0800,             /* dcl_cube s0      */
12717         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12718         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12719         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12720         0x0000ffff,                                     /* end              */
12721     };
12722     static const DWORD ps_code_volume[] =
12723     {
12724         0xffff0200,                                     /* ps_2_0           */
12725         0x0200001f, 0xa0000000, 0xa00f0800,             /* dcl_volume s0    */
12726         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12727         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12728         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12729         0x0000ffff,                                     /* end              */
12730     };
12731
12732     static const struct
12733     {
12734         float x, y, z;
12735         float u, v;
12736     }
12737     quad[] =
12738     {
12739         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12740         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12741         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12742         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12743     };
12744
12745     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12746     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
12747
12748     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12749     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12750     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
12751     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12752     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
12753     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12754
12755     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
12756     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12757
12758     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12759     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12760
12761     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12762     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12763
12764     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
12765     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12766
12767     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
12768     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
12769
12770     hr = IDirect3DDevice9_SetPixelShader(device, ps);
12771     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12772
12773     hr = IDirect3DDevice9_BeginScene(device);
12774     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12775     if(SUCCEEDED(hr))
12776     {
12777         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12778         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12779
12780         hr = IDirect3DDevice9_EndScene(device);
12781         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12782     }
12783
12784     color = getPixelColorFromSurface(rt, 32, 32);
12785     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12786
12787     /* Now try with a cube texture */
12788     hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
12789     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12790
12791     hr = IDirect3DDevice9_BeginScene(device);
12792     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12793     if (SUCCEEDED(hr))
12794     {
12795         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12796         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12797
12798         hr = IDirect3DDevice9_EndScene(device);
12799         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12800     }
12801
12802     color = getPixelColorFromSurface(rt, 32, 32);
12803     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12804
12805     /* And then with a volume texture */
12806     hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
12807     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12808
12809     hr = IDirect3DDevice9_BeginScene(device);
12810     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12811     if (SUCCEEDED(hr))
12812     {
12813         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12814         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12815
12816         hr = IDirect3DDevice9_EndScene(device);
12817         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12818     }
12819
12820     color = getPixelColorFromSurface(rt, 32, 32);
12821     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12822
12823     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12824     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12825
12826     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12827     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12828
12829     IDirect3DSurface9_Release(rt);
12830     IDirect3DSurface9_Release(old_rt);
12831     IDirect3DPixelShader9_Release(ps);
12832     IDirect3DPixelShader9_Release(ps_cube);
12833     IDirect3DPixelShader9_Release(ps_volume);
12834 }
12835
12836 static void update_surface_test(IDirect3DDevice9 *device)
12837 {
12838     static const BYTE blocks[][8] =
12839     {
12840         {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
12841         {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
12842         {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
12843         {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
12844         {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
12845         {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
12846         {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
12847     };
12848     static const struct
12849     {
12850         UINT x, y;
12851         D3DCOLOR color;
12852     }
12853     expected_colors[] =
12854     {
12855         { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
12856         { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
12857         {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
12858         {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12859         {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12860         {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12861         {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
12862     };
12863     static const struct
12864     {
12865         float x, y, z, w;
12866         float u, v;
12867     }
12868     tri[] =
12869     {
12870         {  0.0f, 480.0f, 0.0f,  1.0f,   0.0f, 0.0f},
12871         {  0.0f,   0.0f, 0.0f,  1.0f,   0.0f, 1.0f},
12872         {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
12873     };
12874     static const RECT rect_2x2 = {0, 0, 2, 2};
12875     static const struct
12876     {
12877         UINT src_level;
12878         UINT dst_level;
12879         const RECT *r;
12880         HRESULT hr;
12881     }
12882     block_size_tests[] =
12883     {
12884         {1, 0, NULL,      D3D_OK},
12885         {0, 1, NULL,      D3DERR_INVALIDCALL},
12886         {5, 4, NULL,      D3DERR_INVALIDCALL},
12887         {4, 5, NULL,      D3DERR_INVALIDCALL},
12888         {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
12889         {5, 5, &rect_2x2, D3D_OK},
12890     };
12891
12892     IDirect3DSurface9 *src_surface, *dst_surface;
12893     IDirect3DTexture9 *src_tex, *dst_tex;
12894     IDirect3D9 *d3d;
12895     UINT count, i;
12896     HRESULT hr;
12897
12898     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12899     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12900
12901     hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12902             D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
12903     IDirect3D9_Release(d3d);
12904     if (FAILED(hr))
12905     {
12906         skip("DXT1 not supported, skipping test.\n");
12907         return;
12908     }
12909
12910     IDirect3D9_Release(d3d);
12911
12912     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
12913     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12914     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
12915     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12916
12917     count = IDirect3DTexture9_GetLevelCount(src_tex);
12918     ok(count == 7, "Got level count %u, expected 7.\n", count);
12919
12920     for (i = 0; i < count; ++i)
12921     {
12922         UINT row_count, block_count, x, y;
12923         D3DSURFACE_DESC desc;
12924         BYTE *row, *block;
12925         D3DLOCKED_RECT r;
12926
12927         hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
12928         ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
12929
12930         hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
12931         ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
12932
12933         row_count = ((desc.Height + 3) & ~3) / 4;
12934         block_count = ((desc.Width + 3) & ~3) / 4;
12935         row = r.pBits;
12936
12937         for (y = 0; y < row_count; ++y)
12938         {
12939             block = row;
12940             for (x = 0; x < block_count; ++x)
12941             {
12942                 memcpy(block, blocks[i], sizeof(blocks[i]));
12943                 block += sizeof(blocks[i]);
12944             }
12945             row += r.Pitch;
12946         }
12947
12948         hr = IDirect3DTexture9_UnlockRect(src_tex, i);
12949         ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
12950     }
12951
12952     for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
12953     {
12954         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
12955         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12956         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
12957         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12958
12959         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
12960         ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
12961                 hr, i, block_size_tests[i].hr);
12962
12963         IDirect3DSurface9_Release(dst_surface);
12964         IDirect3DSurface9_Release(src_surface);
12965     }
12966
12967     for (i = 0; i < count; ++i)
12968     {
12969         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
12970         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12971         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
12972         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12973
12974         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
12975         ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
12976
12977         IDirect3DSurface9_Release(dst_surface);
12978         IDirect3DSurface9_Release(src_surface);
12979     }
12980
12981     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12982     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12983     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12984     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12985     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
12986     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12987     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
12988     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12989     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12990     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12991     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12992     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12993
12994     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
12995     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12996
12997     hr = IDirect3DDevice9_BeginScene(device);
12998     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12999     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
13000     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13001     hr = IDirect3DDevice9_EndScene(device);
13002     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13003
13004     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13005     {
13006         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13007         ok(color_match(color, expected_colors[i].color, 0),
13008                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13009                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13010     }
13011
13012     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13013     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13014
13015     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13016     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13017     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
13018     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
13019     IDirect3DTexture9_Release(dst_tex);
13020     IDirect3DTexture9_Release(src_tex);
13021 }
13022
13023 static void multisample_get_rtdata_test(IDirect3DDevice9 *device)
13024 {
13025     IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
13026     IDirect3D9 *d3d9;
13027     HRESULT hr;
13028
13029     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
13030     ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
13031     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13032             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13033     IDirect3D9_Release(d3d9);
13034     if (FAILED(hr))
13035     {
13036         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
13037         return;
13038     }
13039
13040     hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
13041             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13042     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13043     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
13044             D3DPOOL_SYSTEMMEM, &readback, NULL);
13045     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13046
13047     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13048     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13049     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13050     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13051
13052     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13053     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13054     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13055     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13056
13057     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
13058     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13059     hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
13060     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
13061
13062     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13063     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13064     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13065     ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13066
13067     IDirect3DSurface9_Release(original_ds);
13068     IDirect3DSurface9_Release(original_rt);
13069     IDirect3DSurface9_Release(readback);
13070     IDirect3DSurface9_Release(rt);
13071 }
13072
13073 static void multisampled_depth_buffer_test(IDirect3D9 *d3d9)
13074 {
13075     IDirect3DDevice9 *device = 0;
13076     IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
13077     D3DCAPS9 caps;
13078     HRESULT hr;
13079     D3DPRESENT_PARAMETERS present_parameters;
13080     unsigned int i;
13081     static const struct
13082     {
13083         float x, y, z;
13084         D3DCOLOR color;
13085     }
13086     quad_1[] =
13087     {
13088         { -1.0f,  1.0f, 0.0f, 0xffff0000},
13089         {  1.0f,  1.0f, 1.0f, 0xffff0000},
13090         { -1.0f, -1.0f, 0.0f, 0xffff0000},
13091         {  1.0f, -1.0f, 1.0f, 0xffff0000},
13092     },
13093     quad_2[] =
13094     {
13095         { -1.0f,  1.0f, 1.0f, 0xff0000ff},
13096         {  1.0f,  1.0f, 0.0f, 0xff0000ff},
13097         { -1.0f, -1.0f, 1.0f, 0xff0000ff},
13098         {  1.0f, -1.0f, 0.0f, 0xff0000ff},
13099     };
13100     static const struct
13101     {
13102         UINT x, y;
13103         D3DCOLOR color;
13104     }
13105     expected_colors[] =
13106     {
13107         { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13108         {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13109         {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13110         {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13111         { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13112         {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13113         {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13114         {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13115     };
13116
13117     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13118             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13119     if (FAILED(hr))
13120     {
13121         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
13122         return;
13123     }
13124     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13125             D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13126     if (FAILED(hr))
13127     {
13128         skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
13129         return;
13130     }
13131
13132     ZeroMemory(&present_parameters, sizeof(present_parameters));
13133     present_parameters.Windowed = TRUE;
13134     present_parameters.hDeviceWindow = create_window();
13135     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13136     present_parameters.BackBufferWidth = 640;
13137     present_parameters.BackBufferHeight = 480;
13138     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13139     present_parameters.EnableAutoDepthStencil = TRUE;
13140     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13141     present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13142
13143     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13144             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13145             &present_parameters, &device);
13146     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13147
13148     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13149     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13150     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13151     {
13152         skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
13153         goto cleanup;
13154     }
13155
13156     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13157             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13158     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13159     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13160             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13161     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13162
13163     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13164     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13165     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13166     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13167
13168     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13169     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13170     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13171     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13172     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13173     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13174     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13175     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13176     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13177     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13178
13179     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13180     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13181
13182     /* Render onscreen and then offscreen */
13183     hr = IDirect3DDevice9_BeginScene(device);
13184     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13185     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13186     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13187     hr = IDirect3DDevice9_EndScene(device);
13188     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13189
13190     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
13191     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13192     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13193     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13194
13195     hr = IDirect3DDevice9_BeginScene(device);
13196     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13197     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13198     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13199     hr = IDirect3DDevice9_EndScene(device);
13200     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13201
13202     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
13203     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13204
13205     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13206     {
13207         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13208         ok(color_match(color, expected_colors[i].color, 1),
13209                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13210                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13211     }
13212
13213     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13214     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13215     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13216     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13217
13218     /* Render offscreen and then onscreen */
13219     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13220     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13221     IDirect3DSurface9_Release(ds);
13222     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13223             D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13224     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13225     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13226
13227     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13228     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13229
13230     hr = IDirect3DDevice9_BeginScene(device);
13231     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13232     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13233     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13234     hr = IDirect3DDevice9_EndScene(device);
13235     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13236
13237     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13238     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13239     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13240     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13241
13242     hr = IDirect3DDevice9_BeginScene(device);
13243     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13244     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13245     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13246     hr = IDirect3DDevice9_EndScene(device);
13247     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13248
13249     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13250     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13251
13252     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13253     {
13254         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13255         ok(color_match(color, expected_colors[i].color, 1),
13256                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13257                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13258     }
13259
13260     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13261     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13262
13263     IDirect3DSurface9_Release(ds);
13264     IDirect3DSurface9_Release(readback);
13265     IDirect3DSurface9_Release(rt);
13266     IDirect3DSurface9_Release(original_rt);
13267     cleanup_device(device);
13268
13269     ZeroMemory(&present_parameters, sizeof(present_parameters));
13270     present_parameters.Windowed = TRUE;
13271     present_parameters.hDeviceWindow = create_window();
13272     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13273     present_parameters.BackBufferWidth = 640;
13274     present_parameters.BackBufferHeight = 480;
13275     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13276     present_parameters.EnableAutoDepthStencil = TRUE;
13277     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13278     present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13279
13280     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13281             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13282             &present_parameters, &device);
13283     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13284
13285     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
13286     ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
13287
13288     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13289             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13290     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13291     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13292             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13293     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13294     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13295             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
13296     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13297
13298     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13299     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13300     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13301     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13302     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13303     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13304     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13305     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13306
13307     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13308     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13309     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13310     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13311     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13312     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13313     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13314     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13315     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13316     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13317
13318     /* Render to a multisampled offscreen frame buffer and then blit to
13319      * the onscreen (not multisampled) frame buffer. */
13320     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13321     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13322
13323     hr = IDirect3DDevice9_BeginScene(device);
13324     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13325     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13326     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13327     hr = IDirect3DDevice9_EndScene(device);
13328     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13329
13330     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13331     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13332     hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
13333     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13334
13335     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13336     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13337     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13338     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13339
13340     hr = IDirect3DDevice9_BeginScene(device);
13341     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13342     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13343     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13344     hr = IDirect3DDevice9_EndScene(device);
13345     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13346
13347     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13348     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13349
13350     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13351     {
13352         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13353         if (i % 4 < 2)
13354             todo_wine ok(color_match(color, expected_colors[i].color, 1),
13355                     "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13356                     expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13357         else
13358             ok(color_match(color, expected_colors[i].color, 1),
13359                     "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13360                     expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13361     }
13362
13363     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13364     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13365
13366     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13367     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13368     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13369     ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13370
13371     IDirect3DSurface9_Release(original_ds);
13372     IDirect3DSurface9_Release(original_rt);
13373     IDirect3DSurface9_Release(ds);
13374     IDirect3DSurface9_Release(readback);
13375     IDirect3DSurface9_Release(rt);
13376 cleanup:
13377     cleanup_device(device);
13378 }
13379
13380 static void resz_test(IDirect3D9 *d3d9)
13381 {
13382     IDirect3DDevice9 *device = 0;
13383     IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
13384     D3DCAPS9 caps;
13385     HRESULT hr;
13386     D3DPRESENT_PARAMETERS present_parameters;
13387     unsigned int i;
13388     static const DWORD ps_code[] =
13389     {
13390         0xffff0200,                                                             /* ps_2_0                       */
13391         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
13392         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
13393         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
13394         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
13395         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
13396         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
13397         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
13398         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
13399         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
13400         0x0000ffff,                                                             /* end                          */
13401     };
13402     struct
13403     {
13404         float x, y, z;
13405         float s, t, p, q;
13406     }
13407     quad[] =
13408     {
13409         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13410         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13411         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13412         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13413     };
13414     struct
13415     {
13416         UINT x, y;
13417         D3DCOLOR color;
13418     }
13419     expected_colors[] =
13420     {
13421         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13422         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13423         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13424         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13425         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13426         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13427         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13428         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13429     };
13430     IDirect3DTexture9 *texture;
13431     IDirect3DPixelShader9 *ps;
13432     DWORD value;
13433
13434     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13435             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13436     if (FAILED(hr))
13437     {
13438         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
13439         return;
13440     }
13441     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13442             D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13443     if (FAILED(hr))
13444     {
13445         skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
13446         return;
13447     }
13448
13449     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13450             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
13451     if (FAILED(hr))
13452     {
13453         skip("No INTZ support, skipping RESZ test.\n");
13454         return;
13455     }
13456
13457     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13458             D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'));
13459     if (FAILED(hr))
13460     {
13461         skip("No RESZ support, skipping RESZ test.\n");
13462         return;
13463     }
13464
13465     ZeroMemory(&present_parameters, sizeof(present_parameters));
13466     present_parameters.Windowed = TRUE;
13467     present_parameters.hDeviceWindow = create_window();
13468     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13469     present_parameters.BackBufferWidth = 640;
13470     present_parameters.BackBufferHeight = 480;
13471     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13472     present_parameters.EnableAutoDepthStencil = FALSE;
13473     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13474     present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13475
13476     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13477             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13478     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13479
13480     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13481     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13482     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
13483     {
13484         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
13485         cleanup_device(device);
13486         return;
13487     }
13488     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13489     {
13490         skip("No unconditional NP2 texture support, skipping INTZ test.\n");
13491         cleanup_device(device);
13492         return;
13493     }
13494
13495     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13496     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13497
13498     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13499             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13500     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13501     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13502             D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13503     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13504             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13505     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13506
13507     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13508             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13509     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13510     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13511     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13512     hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13513     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13514     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13515     ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13516     IDirect3DSurface9_Release(intz_ds);
13517     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13518     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13519
13520     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13521     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13522     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13523     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13524     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13525     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13526     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13527     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13528     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13529     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13530
13531     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13532     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13533     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13534     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13535     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13536     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13537     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13538     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13539     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13540     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13541
13542     /* Render offscreen (multisampled), blit the depth buffer
13543      * into the INTZ texture and then check its contents */
13544     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13545     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13546     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13547     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13548     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13549     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13550
13551     hr = IDirect3DDevice9_BeginScene(device);
13552     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13553     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13554     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13555
13556     /* The destination depth texture has to be bound to sampler 0 */
13557     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13558     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13559
13560     /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
13561     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13562     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13563     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13564     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13565     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13566     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13567     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13568     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13569     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13570     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13571     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13572     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13573     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13574     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13575
13576     /* The actual multisampled depth buffer resolve happens here */
13577     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13578     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13579     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13580     ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13581
13582     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13583     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13584     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13585     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13586
13587     /* Read the depth values back */
13588     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13589     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13590     hr = IDirect3DDevice9_EndScene(device);
13591     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13592
13593     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13594     {
13595         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13596         ok(color_match(color, expected_colors[i].color, 1),
13597                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13598                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13599     }
13600
13601     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13602     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13603
13604     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13605     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13606     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13607     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13608     IDirect3DSurface9_Release(ds);
13609     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13610     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13611     IDirect3DTexture9_Release(texture);
13612     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13613     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13614     IDirect3DPixelShader9_Release(ps);
13615     IDirect3DSurface9_Release(readback);
13616     IDirect3DSurface9_Release(original_rt);
13617     IDirect3DSurface9_Release(rt);
13618     cleanup_device(device);
13619
13620
13621     ZeroMemory(&present_parameters, sizeof(present_parameters));
13622     present_parameters.Windowed = TRUE;
13623     present_parameters.hDeviceWindow = create_window();
13624     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13625     present_parameters.BackBufferWidth = 640;
13626     present_parameters.BackBufferHeight = 480;
13627     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13628     present_parameters.EnableAutoDepthStencil = TRUE;
13629     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13630     present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13631
13632     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13633             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13634     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13635
13636     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13637     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13638     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13639     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13640     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13641             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13642     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13643     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13644             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13645     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13646     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13647     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13648     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13649     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13650     hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13651     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13652     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13653     ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13654     IDirect3DSurface9_Release(intz_ds);
13655     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13656     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13657
13658     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13659     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13660     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13661     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13662     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13663     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13664     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13665     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13666     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13667     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13668
13669     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13670     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13671     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13672     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13673     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13674     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13675     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13676     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13677     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13678     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13679
13680     /* Render onscreen, blit the depth buffer into the INTZ texture
13681      * and then check its contents */
13682     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13683     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13684     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13685     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13686     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13687     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13688
13689     hr = IDirect3DDevice9_BeginScene(device);
13690     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13691     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13692     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13693     hr = IDirect3DDevice9_EndScene(device);
13694     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13695
13696     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13697     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13698
13699     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13700     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13701     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13702     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13703     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13704     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13705     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13706     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13707     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13708     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13709     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13710     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13711     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13712     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13713
13714     /* The actual multisampled depth buffer resolve happens here */
13715     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13716     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13717     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13718     ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13719
13720     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13721     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13722     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13723     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13724
13725     /* Read the depth values back */
13726     hr = IDirect3DDevice9_BeginScene(device);
13727     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13728     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13729     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13730     hr = IDirect3DDevice9_EndScene(device);
13731     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13732
13733     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13734     {
13735         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13736         ok(color_match(color, expected_colors[i].color, 1),
13737                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13738                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13739     }
13740
13741     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13742     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13743
13744
13745     /* Test edge cases - try with no texture at all */
13746     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13747     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13748     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13749     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13750
13751     hr = IDirect3DDevice9_BeginScene(device);
13752     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13753     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13754     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13755     hr = IDirect3DDevice9_EndScene(device);
13756     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13757
13758     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13759     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13760
13761     /* With a non-multisampled depth buffer */
13762     IDirect3DSurface9_Release(ds);
13763     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13764             D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
13765
13766     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13767     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13768     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13769     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13770     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13771     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13772
13773     hr = IDirect3DDevice9_BeginScene(device);
13774     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13775     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13776     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13777
13778     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13779     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13780
13781     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13782     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13783     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13784     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13785     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13786     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13787     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13788     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13789     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13790     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13791     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13792     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13793     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13794     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13795     hr = IDirect3DDevice9_EndScene(device);
13796     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13797
13798     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13799     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13800
13801     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13802     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13803
13804     /* Read the depth values back. */
13805     hr = IDirect3DDevice9_BeginScene(device);
13806     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13807     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13808     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13809     hr = IDirect3DDevice9_EndScene(device);
13810     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13811
13812     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13813     {
13814         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13815         ok(color_match(color, expected_colors[i].color, 1),
13816                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13817                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13818     }
13819
13820     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13821     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13822
13823     /* Without a current depth-stencil buffer set */
13824     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13825     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13826     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13827     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13828
13829     hr = IDirect3DDevice9_BeginScene(device);
13830     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13831     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13832     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13833     hr = IDirect3DDevice9_EndScene(device);
13834     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13835
13836     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13837     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13838
13839     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13840     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13841     IDirect3DSurface9_Release(ds);
13842     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13843     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13844     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13845     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13846     IDirect3DTexture9_Release(texture);
13847     IDirect3DPixelShader9_Release(ps);
13848     IDirect3DSurface9_Release(readback);
13849     IDirect3DSurface9_Release(original_rt);
13850     cleanup_device(device);
13851 }
13852
13853 static void zenable_test(IDirect3DDevice9 *device)
13854 {
13855     static const struct
13856     {
13857         struct vec4 position;
13858         D3DCOLOR diffuse;
13859     }
13860     tquad[] =
13861     {
13862         {{  0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
13863         {{  0.0f,   0.0f, -0.5f, 1.0f}, 0xff00ff00},
13864         {{640.0f, 480.0f,  1.5f, 1.0f}, 0xff00ff00},
13865         {{640.0f,   0.0f,  1.5f, 1.0f}, 0xff00ff00},
13866     };
13867     D3DCOLOR color;
13868     D3DCAPS9 caps;
13869     HRESULT hr;
13870     UINT x, y;
13871     UINT i, j;
13872
13873     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
13874     ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
13875     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13876     ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
13877
13878     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
13879     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13880     hr = IDirect3DDevice9_BeginScene(device);
13881     ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13882     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
13883     ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13884     hr = IDirect3DDevice9_EndScene(device);
13885     ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13886
13887     for (i = 0; i < 4; ++i)
13888     {
13889         for (j = 0; j < 4; ++j)
13890         {
13891             x = 80 * ((2 * j) + 1);
13892             y = 60 * ((2 * i) + 1);
13893             color = getPixelColor(device, x, y);
13894             ok(color_match(color, 0x0000ff00, 1),
13895                     "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
13896         }
13897     }
13898
13899     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13900     ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
13901
13902     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13903     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13904
13905     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
13906             && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
13907     {
13908         static const DWORD vs_code[] =
13909         {
13910             0xfffe0101,                                 /* vs_1_1           */
13911             0x0000001f, 0x80000000, 0x900f0000,         /* dcl_position v0  */
13912             0x00000001, 0xc00f0000, 0x90e40000,         /* mov oPos, v0     */
13913             0x00000001, 0xd00f0000, 0x90e40000,         /* mov oD0, v0      */
13914             0x0000ffff
13915         };
13916         static const DWORD ps_code[] =
13917         {
13918             0xffff0101,                                 /* ps_1_1           */
13919             0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
13920             0x0000ffff                                  /* end              */
13921         };
13922         static const struct vec3 quad[] =
13923         {
13924             {-1.0f, -1.0f, -0.5f},
13925             {-1.0f,  1.0f, -0.5f},
13926             { 1.0f, -1.0f,  1.5f},
13927             { 1.0f,  1.0f,  1.5f},
13928         };
13929         static const D3DCOLOR expected[] =
13930         {
13931             0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
13932             0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
13933             0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
13934             0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
13935         };
13936
13937         IDirect3DVertexShader9 *vs;
13938         IDirect3DPixelShader9 *ps;
13939
13940         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13941         ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
13942         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
13943         ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
13944         hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13945         ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
13946         hr = IDirect3DDevice9_SetVertexShader(device, vs);
13947         ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13948         hr = IDirect3DDevice9_SetPixelShader(device, ps);
13949         ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
13950
13951         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
13952         ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13953         hr = IDirect3DDevice9_BeginScene(device);
13954         ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13955         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13956         ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13957         hr = IDirect3DDevice9_EndScene(device);
13958         ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13959
13960         for (i = 0; i < 4; ++i)
13961         {
13962             for (j = 0; j < 4; ++j)
13963             {
13964                 x = 80 * ((2 * j) + 1);
13965                 y = 60 * ((2 * i) + 1);
13966                 color = getPixelColor(device, x, y);
13967                 ok(color_match(color, expected[i * 4 + j], 1),
13968                         "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
13969             }
13970         }
13971
13972         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13973         ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
13974
13975         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13976         ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
13977         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
13978         ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13979         IDirect3DPixelShader9_Release(ps);
13980         IDirect3DVertexShader9_Release(vs);
13981     }
13982 }
13983
13984 START_TEST(visual)
13985 {
13986     IDirect3D9 *d3d9;
13987     IDirect3DDevice9 *device_ptr;
13988     D3DCAPS9 caps;
13989     HRESULT hr;
13990     DWORD color;
13991
13992     d3d9_handle = LoadLibraryA("d3d9.dll");
13993     if (!d3d9_handle)
13994     {
13995         skip("Could not load d3d9.dll\n");
13996         return;
13997     }
13998
13999     device_ptr = init_d3d9();
14000     if (!device_ptr)
14001     {
14002         skip("Creating the device failed\n");
14003         return;
14004     }
14005
14006     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
14007
14008     /* Check for the reliability of the returned data */
14009     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
14010     if(FAILED(hr))
14011     {
14012         skip("Clear failed, can't assure correctness of the test results, skipping\n");
14013         goto cleanup;
14014     }
14015
14016     color = getPixelColor(device_ptr, 1, 1);
14017     if(color !=0x00ff0000)
14018     {
14019         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
14020         goto cleanup;
14021     }
14022     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
14023
14024     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
14025     if(FAILED(hr))
14026     {
14027         skip("Clear failed, can't assure correctness of the test results, skipping\n");
14028         goto cleanup;
14029     }
14030
14031     color = getPixelColor(device_ptr, 639, 479);
14032     if(color != 0x0000ddee)
14033     {
14034         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
14035         goto cleanup;
14036     }
14037     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
14038
14039     /* Now execute the real tests */
14040     depth_clamp_test(device_ptr);
14041     stretchrect_test(device_ptr);
14042     lighting_test(device_ptr);
14043     clear_test(device_ptr);
14044     color_fill_test(device_ptr);
14045     fog_test(device_ptr);
14046     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
14047     {
14048         test_cube_wrap(device_ptr);
14049     } else {
14050         skip("No cube texture support\n");
14051     }
14052     z_range_test(device_ptr);
14053     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
14054     {
14055         maxmip_test(device_ptr);
14056     }
14057     else
14058     {
14059         skip("No mipmap support\n");
14060     }
14061     offscreen_test(device_ptr);
14062     ds_size_test(device_ptr);
14063     alpha_test(device_ptr);
14064     shademode_test(device_ptr);
14065     srgbtexture_test(device_ptr);
14066     release_buffer_test(device_ptr);
14067     float_texture_test(device_ptr);
14068     g16r16_texture_test(device_ptr);
14069     pixelshader_blending_test(device_ptr);
14070     texture_transform_flags_test(device_ptr);
14071     autogen_mipmap_test(device_ptr);
14072     fixed_function_decl_test(device_ptr);
14073     conditional_np2_repeat_test(device_ptr);
14074     fixed_function_bumpmap_test(device_ptr);
14075     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
14076         stencil_cull_test(device_ptr);
14077     } else {
14078         skip("No two sided stencil support\n");
14079     }
14080     pointsize_test(device_ptr);
14081     tssargtemp_test(device_ptr);
14082     np2_stretch_rect_test(device_ptr);
14083     yuv_color_test(device_ptr);
14084     zwriteenable_test(device_ptr);
14085     alphatest_test(device_ptr);
14086     viewport_test(device_ptr);
14087
14088     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
14089     {
14090         test_constant_clamp_vs(device_ptr);
14091         test_compare_instructions(device_ptr);
14092     }
14093     else skip("No vs_1_1 support\n");
14094
14095     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
14096     {
14097         test_mova(device_ptr);
14098         loop_index_test(device_ptr);
14099         sincos_test(device_ptr);
14100         sgn_test(device_ptr);
14101         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14102             test_vshader_input(device_ptr);
14103             test_vshader_float16(device_ptr);
14104             stream_test(device_ptr);
14105         } else {
14106             skip("No vs_3_0 support\n");
14107         }
14108     }
14109     else skip("No vs_2_0 support\n");
14110
14111     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0) && caps.PixelShaderVersion >= D3DPS_VERSION(2, 0))
14112     {
14113         fog_with_shader_test(device_ptr);
14114     }
14115     else skip("No vs_2_0 and ps_2_0 support\n");
14116
14117     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
14118     {
14119         texbem_test(device_ptr);
14120         texdepth_test(device_ptr);
14121         texkill_test(device_ptr);
14122         x8l8v8u8_test(device_ptr);
14123         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
14124             constant_clamp_ps_test(device_ptr);
14125             cnd_test(device_ptr);
14126             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
14127                 dp2add_ps_test(device_ptr);
14128                 unbound_sampler_test(device_ptr);
14129                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14130                     nested_loop_test(device_ptr);
14131                     pretransformed_varying_test(device_ptr);
14132                     vFace_register_test(device_ptr);
14133                     vpos_register_test(device_ptr);
14134                     multiple_rendertargets_test(device_ptr);
14135                 } else {
14136                     skip("No ps_3_0 or vs_3_0 support\n");
14137                 }
14138             } else {
14139                 skip("No ps_2_0 support\n");
14140             }
14141         }
14142     }
14143     else skip("No ps_1_1 support\n");
14144
14145     texop_test(device_ptr);
14146     texop_range_test(device_ptr);
14147     alphareplicate_test(device_ptr);
14148     dp3_alpha_test(device_ptr);
14149     depth_buffer_test(device_ptr);
14150     depth_buffer2_test(device_ptr);
14151     depth_blit_test(device_ptr);
14152     intz_test(device_ptr);
14153     shadow_test(device_ptr);
14154     fp_special_test(device_ptr);
14155     depth_bounds_test(device_ptr);
14156     srgbwrite_format_test(device_ptr);
14157     clip_planes_test(device_ptr);
14158     update_surface_test(device_ptr);
14159     multisample_get_rtdata_test(device_ptr);
14160     zenable_test(device_ptr);
14161
14162     hr = IDirect3DDevice9_GetDirect3D(device_ptr, &d3d9);
14163     ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
14164     cleanup_device(device_ptr);
14165     device_ptr = NULL;
14166
14167     multisampled_depth_buffer_test(d3d9);
14168     resz_test(d3d9);
14169
14170     IDirect3D9_Release(d3d9);
14171
14172 cleanup:
14173     cleanup_device(device_ptr);
14174 }