d3d9/tests: Don't test for equality in d3d9's depth_blit_test.
[wine] / dlls / d3d9 / tests / visual.c
1 /*
2  * Copyright 2005, 2007-2008 Henri Verbeet
3  * Copyright (C) 2007-2013 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     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
683     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
684
685     rect[0].x1 = 0;
686     rect[0].y1 = 0;
687     rect[0].x2 = 640;
688     rect[0].y2 = 480;
689     hr = IDirect3DDevice9_Clear(device, 0, rect, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
690     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
691
692     color = getPixelColor(device, 320, 240);
693     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
694             "Clear with count = 0, rect != NULL has color %08x\n", color);
695
696     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
697
698     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
699     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
700     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
701     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
702
703     color = getPixelColor(device, 320, 240);
704     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
705             "Clear with count = 1, rect = NULL has color %08x\n", color);
706
707     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
708 }
709
710 static void color_fill_test(IDirect3DDevice9 *device)
711 {
712     HRESULT hr;
713     IDirect3DSurface9 *backbuffer = NULL;
714     IDirect3DSurface9 *rt_surface = NULL;
715     IDirect3DSurface9 *offscreen_surface = NULL;
716     DWORD fill_color, color;
717
718     /* Test ColorFill on a the backbuffer (should pass) */
719     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
720     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
721     if(backbuffer)
722     {
723         fill_color = 0x112233;
724         hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
725         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
726
727         color = getPixelColor(device, 0, 0);
728         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
729
730         IDirect3DSurface9_Release(backbuffer);
731     }
732
733     /* Test ColorFill on a render target surface (should pass) */
734     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
735     ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
736     if(rt_surface)
737     {
738         fill_color = 0x445566;
739         hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
740         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
741
742         color = getPixelColorFromSurface(rt_surface, 0, 0);
743         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
744
745         IDirect3DSurface9_Release(rt_surface);
746     }
747
748     /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
749     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
750             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
751     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
752     if(offscreen_surface)
753     {
754         fill_color = 0x778899;
755         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
756         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
757
758         color = getPixelColorFromSurface(offscreen_surface, 0, 0);
759         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
760
761         IDirect3DSurface9_Release(offscreen_surface);
762     }
763
764     /* Try ColorFill on a offscreen surface in sysmem (should fail) */
765     offscreen_surface = NULL;
766     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
767             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
768     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
769     if(offscreen_surface)
770     {
771         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
772         ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
773
774         IDirect3DSurface9_Release(offscreen_surface);
775     }
776 }
777
778 typedef struct {
779     float in[4];
780     DWORD out;
781 } test_data_t;
782
783 /*
784  *  c7      mova    ARGB            mov     ARGB
785  * -2.4     -2      0x00ffff00      -3      0x00ff0000
786  * -1.6     -2      0x00ffff00      -2      0x00ffff00
787  * -0.4      0      0x0000ffff      -1      0x0000ff00
788  *  0.4      0      0x0000ffff       0      0x0000ffff
789  *  1.6      2      0x00ff00ff       1      0x000000ff
790  *  2.4      2      0x00ff00ff       2      0x00ff00ff
791  */
792 static void test_mova(IDirect3DDevice9 *device)
793 {
794     static const DWORD mova_test[] = {
795         0xfffe0200,                                                             /* vs_2_0                       */
796         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
797         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
798         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
799         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
800         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
801         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
802         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
803         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
804         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
805         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
806         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
807         0x0000ffff                                                              /* END                          */
808     };
809     static const DWORD mov_test[] = {
810         0xfffe0101,                                                             /* vs_1_1                       */
811         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
812         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
813         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
814         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
815         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
816         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
817         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
818         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
819         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
820         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
821         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
822         0x0000ffff                                                              /* END                          */
823     };
824
825     static const test_data_t test_data[2][6] = {
826         {
827             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
828             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
829             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
830             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
831             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
832             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
833         },
834         {
835             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
836             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
837             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
838             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
839             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
840             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
841         }
842     };
843
844     static const float quad[][3] = {
845         {-1.0f, -1.0f, 0.0f},
846         {-1.0f,  1.0f, 0.0f},
847         { 1.0f, -1.0f, 0.0f},
848         { 1.0f,  1.0f, 0.0f},
849     };
850
851     static const D3DVERTEXELEMENT9 decl_elements[] = {
852         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
853         D3DDECL_END()
854     };
855
856     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
857     IDirect3DVertexShader9 *mova_shader = NULL;
858     IDirect3DVertexShader9 *mov_shader = NULL;
859     HRESULT hr;
860     UINT i, j;
861
862     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
863     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
864     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
865     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
866     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
867     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
868     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
869     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
870
871     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
872     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
873     for(j = 0; j < 2; ++j)
874     {
875         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
876         {
877             DWORD color;
878
879             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
880             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
881
882             hr = IDirect3DDevice9_BeginScene(device);
883             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
884
885             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
886             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
887
888             hr = IDirect3DDevice9_EndScene(device);
889             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
890
891             color = getPixelColor(device, 320, 240);
892             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
893                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
894
895             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
896             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
897
898             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
899             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
900         }
901         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
902         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
903     }
904
905     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
906     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
907
908     IDirect3DVertexDeclaration9_Release(vertex_declaration);
909     IDirect3DVertexShader9_Release(mova_shader);
910     IDirect3DVertexShader9_Release(mov_shader);
911 }
912
913 struct sVertex {
914     float x, y, z;
915     DWORD diffuse;
916     DWORD specular;
917 };
918
919 struct sVertexT {
920     float x, y, z, rhw;
921     DWORD diffuse;
922     DWORD specular;
923 };
924
925 static void fog_test(IDirect3DDevice9 *device)
926 {
927     HRESULT hr;
928     D3DCOLOR color;
929     float start = 0.0f, end = 1.0f;
930     D3DCAPS9 caps;
931     int i;
932
933     /* Gets full z based fog with linear fog, no fog with specular color */
934     struct sVertex untransformed_1[] = {
935         {-1,    -1,   0.1f,         0xffff0000,     0xff000000  },
936         {-1,     0,   0.1f,         0xffff0000,     0xff000000  },
937         { 0,     0,   0.1f,         0xffff0000,     0xff000000  },
938         { 0,    -1,   0.1f,         0xffff0000,     0xff000000  },
939     };
940     /* Ok, I am too lazy to deal with transform matrices */
941     struct sVertex untransformed_2[] = {
942         {-1,     0,   1.0f,         0xffff0000,     0xff000000  },
943         {-1,     1,   1.0f,         0xffff0000,     0xff000000  },
944         { 0,     1,   1.0f,         0xffff0000,     0xff000000  },
945         { 0,     0,   1.0f,         0xffff0000,     0xff000000  },
946     };
947     /* Untransformed ones. Give them a different diffuse color to make the test look
948      * nicer. It also makes making sure that they are drawn correctly easier.
949      */
950     struct sVertexT transformed_1[] = {
951         {320,    0,   1.0f, 1.0f,   0xffffff00,     0xff000000  },
952         {640,    0,   1.0f, 1.0f,   0xffffff00,     0xff000000  },
953         {640,  240,   1.0f, 1.0f,   0xffffff00,     0xff000000  },
954         {320,  240,   1.0f, 1.0f,   0xffffff00,     0xff000000  },
955     };
956     struct sVertexT transformed_2[] = {
957         {320,  240,   1.0f, 1.0f,   0xffffff00,     0xff000000  },
958         {640,  240,   1.0f, 1.0f,   0xffffff00,     0xff000000  },
959         {640,  480,   1.0f, 1.0f,   0xffffff00,     0xff000000  },
960         {320,  480,   1.0f, 1.0f,   0xffffff00,     0xff000000  },
961     };
962     struct vertex rev_fog_quads[] = {
963        {-1.0,   -1.0,   0.1,    0x000000ff},
964        {-1.0,    0.0,   0.1,    0x000000ff},
965        { 0.0,    0.0,   0.1,    0x000000ff},
966        { 0.0,   -1.0,   0.1,    0x000000ff},
967
968        { 0.0,   -1.0,   0.9,    0x000000ff},
969        { 0.0,    0.0,   0.9,    0x000000ff},
970        { 1.0,    0.0,   0.9,    0x000000ff},
971        { 1.0,   -1.0,   0.9,    0x000000ff},
972
973        { 0.0,    0.0,   0.4,    0x000000ff},
974        { 0.0,    1.0,   0.4,    0x000000ff},
975        { 1.0,    1.0,   0.4,    0x000000ff},
976        { 1.0,    0.0,   0.4,    0x000000ff},
977
978        {-1.0,    0.0,   0.7,    0x000000ff},
979        {-1.0,    1.0,   0.7,    0x000000ff},
980        { 0.0,    1.0,   0.7,    0x000000ff},
981        { 0.0,    0.0,   0.7,    0x000000ff},
982     };
983     WORD Indices[] = {0, 1, 2, 2, 3, 0};
984
985     const float ident_mat[16] =
986     {
987         1.0f, 0.0f, 0.0f, 0.0f,
988         0.0f, 1.0f, 0.0f, 0.0f,
989         0.0f, 0.0f, 1.0f, 0.0f,
990         0.0f, 0.0f, 0.0f, 1.0f
991     };
992     const float world_mat1[16] =
993     {
994         1.0f, 0.0f,  0.0f, 0.0f,
995         0.0f, 1.0f,  0.0f, 0.0f,
996         0.0f, 0.0f,  1.0f, 0.0f,
997         0.0f, 0.0f, -0.5f, 1.0f
998     };
999     const float world_mat2[16] =
1000     {
1001         1.0f, 0.0f, 0.0f, 0.0f,
1002         0.0f, 1.0f, 0.0f, 0.0f,
1003         0.0f, 0.0f, 1.0f, 0.0f,
1004         0.0f, 0.0f, 1.0f, 1.0f
1005     };
1006     const float proj_mat[16] =
1007     {
1008         1.0f, 0.0f,  0.0f, 0.0f,
1009         0.0f, 1.0f,  0.0f, 0.0f,
1010         0.0f, 0.0f,  1.0f, 0.0f,
1011         0.0f, 0.0f, -1.0f, 1.0f
1012     };
1013
1014     const struct sVertex far_quad1[] =
1015     {
1016         {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1017         {-1.0f,  0.0f, 0.5f, 0xffff0000, 0xff000000},
1018         { 0.0f,  0.0f, 0.5f, 0xffff0000, 0xff000000},
1019         { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1020     };
1021     const struct sVertex far_quad2[] =
1022     {
1023         {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1024         {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1025         { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1026         { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1027     };
1028
1029     memset(&caps, 0, sizeof(caps));
1030     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1031     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
1032     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1033     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1034
1035     /* Setup initial states: No lighting, fog on, fog color */
1036     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1037     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1038     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1039     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1040     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
1041     ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1042
1043     /* First test: Both table fog and vertex fog off */
1044     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1045     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1046     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1047     ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1048
1049     /* Start = 0, end = 1. Should be default, but set them */
1050     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1051     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1052     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1053     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1054
1055     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1056     {
1057         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1058         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1059         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
1060         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1061                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1062                                                      sizeof(untransformed_1[0]));
1063         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1064
1065         /* That makes it use the Z value */
1066         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1067         ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
1068         /* Untransformed, vertex fog != none (or table fog != none):
1069          * Use the Z value as input into the equation
1070          */
1071         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1072                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1073                                                      sizeof(untransformed_2[0]));
1074         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1075
1076         /* transformed verts */
1077         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1078         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1079         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1080         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1081                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1082                                                      sizeof(transformed_1[0]));
1083         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1084
1085         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1086         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1087         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
1088          * equation
1089          */
1090         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1091                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
1092                                                      sizeof(transformed_2[0]));
1093         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1094
1095         hr = IDirect3DDevice9_EndScene(device);
1096         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1097     }
1098     else
1099     {
1100         ok(FALSE, "BeginScene failed\n");
1101     }
1102
1103     color = getPixelColor(device, 160, 360);
1104     ok(color == 0x00ff0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1105     color = getPixelColor(device, 160, 120);
1106     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1107     color = getPixelColor(device, 480, 120);
1108     ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1109     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1110     {
1111         color = getPixelColor(device, 480, 360);
1112         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1113     }
1114     else
1115     {
1116         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1117          * The settings above result in no fogging with vertex fog
1118          */
1119         color = getPixelColor(device, 480, 120);
1120         ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1121         trace("Info: Table fog not supported by this device\n");
1122     }
1123     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1124
1125     /* Now test the special case fogstart == fogend */
1126     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1127     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1128
1129     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1130     {
1131         start = 512;
1132         end = 512;
1133         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1134         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1135         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1136         ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1137
1138         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1139         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1140         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1141         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1142         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1143         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1144
1145         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1146          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1147          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1148          * The third transformed quad remains unfogged because the fogcoords are read from the specular
1149          * color and has fixed fogstart and fogend.
1150          */
1151         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1152                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1153                 sizeof(untransformed_1[0]));
1154         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1155         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1156                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1157                 sizeof(untransformed_2[0]));
1158         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1159
1160         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1161         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1162         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1163         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1164                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1165                 sizeof(transformed_1[0]));
1166         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1167
1168         hr = IDirect3DDevice9_EndScene(device);
1169         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1170     }
1171     else
1172     {
1173         ok(FALSE, "BeginScene failed\n");
1174     }
1175     color = getPixelColor(device, 160, 360);
1176     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1177     color = getPixelColor(device, 160, 120);
1178     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1179     color = getPixelColor(device, 480, 120);
1180     ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1181     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1182
1183     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1184      * but without shaders it seems to work everywhere
1185      */
1186     end = 0.2;
1187     start = 0.8;
1188     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1189     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1190     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1191     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1192     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1193     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1194
1195     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1196      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1197      * so skip this for now
1198      */
1199     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1200         const char *mode = (i ? "table" : "vertex");
1201         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1202         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1203         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1204         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1205         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1206         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1207         hr = IDirect3DDevice9_BeginScene(device);
1208         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1209         if(SUCCEEDED(hr)) {
1210             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1211                                 4,  5,  6,  6,  7, 4,
1212                                 8,  9, 10, 10, 11, 8,
1213                             12, 13, 14, 14, 15, 12};
1214
1215             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1216                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1217                     sizeof(rev_fog_quads[0]));
1218             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1219
1220             hr = IDirect3DDevice9_EndScene(device);
1221             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1222         }
1223         color = getPixelColor(device, 160, 360);
1224         ok(color_match(color, 0x0000ff00, 1),
1225                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1226
1227         color = getPixelColor(device, 160, 120);
1228         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1229                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1230
1231         color = getPixelColor(device, 480, 120);
1232         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1233                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1234
1235         color = getPixelColor(device, 480, 360);
1236         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1237
1238         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1239
1240         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1241             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1242             break;
1243         }
1244     }
1245
1246     if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1247     {
1248         /* A simple fog + non-identity world matrix test */
1249         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat1);
1250         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
1251
1252         start = 0.0;
1253         end = 1.0;
1254         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1255         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1256         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1257         ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1258         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1259         ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1260         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1261         ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1262
1263         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1264         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
1265
1266         if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1267         {
1268             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1269             ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1270
1271             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1272                     2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1273             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1274
1275             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1276                     2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1277             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1278
1279             hr = IDirect3DDevice9_EndScene(device);
1280             ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1281         }
1282         else
1283         {
1284             ok(FALSE, "BeginScene failed\n");
1285         }
1286
1287         color = getPixelColor(device, 160, 360);
1288         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
1289                 "Unfogged quad has color %08x\n", color);
1290         color = getPixelColor(device, 160, 120);
1291         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1292                 "Fogged out quad has color %08x\n", color);
1293
1294         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1295
1296         /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
1297         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat2);
1298         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1299         hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)proj_mat);
1300         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1301
1302         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1303         ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1304
1305         if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1306         {
1307             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1308             ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1309
1310             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1311                     2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1312             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1313
1314             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1315                     2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1316             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1317
1318             hr = IDirect3DDevice9_EndScene(device);
1319             ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1320         }
1321         else
1322         {
1323             ok(FALSE, "BeginScene failed\n");
1324         }
1325
1326         color = getPixelColor(device, 160, 360);
1327         todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1328         color = getPixelColor(device, 160, 120);
1329         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1330                 "Fogged out quad has color %08x\n", color);
1331
1332         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1333
1334         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)ident_mat);
1335         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1336         hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)ident_mat);
1337         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1338     }
1339     else
1340     {
1341         skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1342     }
1343
1344     /* Test RANGEFOG vs FOGTABLEMODE */
1345     if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
1346             (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
1347     {
1348         struct sVertex untransformed_3[] =
1349         {
1350             {-1.0,-1.0,   0.4999f,      0xffff0000,     0xff000000  },
1351             {-1.0, 1.0,   0.4999f,      0xffff0000,     0xff000000  },
1352             { 1.0,-1.0,   0.4999f,      0xffff0000,     0xff000000  },
1353             { 1.0, 1.0,   0.4999f,      0xffff0000,     0xff000000  },
1354         };
1355
1356         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1357         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
1358         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1359         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
1360
1361         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
1362         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1363
1364         /* z=0.4999, set the fogstart to 0.5 and fogend slightly higher. If range fog
1365          * is not used, the fog coordinate will be equal to fogstart and the quad not
1366          * fogged. If range fog is used the fog coordinate will be slightly higher and
1367          * the fog coordinate will be > fogend, so we get a fully fogged quad. The fog
1368          * is calculated per vertex and interpolated, so even the center of the screen
1369          * where the difference doesn't matter will be fogged, but check the corners in
1370          * case a d3d/gl implementation decides to calculate the fog factor per fragment */
1371         start = 0.5f;
1372         end = 0.50001f;
1373         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1374         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1375         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1376         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1377
1378         /* Table fog: Range fog is not used */
1379         hr = IDirect3DDevice9_BeginScene(device);
1380         ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
1381         if (SUCCEEDED(hr))
1382         {
1383             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1384             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1385             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1386             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1387             hr = IDirect3DDevice9_EndScene(device);
1388             ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1389         }
1390         color = getPixelColor(device, 10, 10);
1391         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1392         color = getPixelColor(device, 630, 10);
1393         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1394         color = getPixelColor(device, 10, 470);
1395         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1396         color = getPixelColor(device, 630, 470);
1397         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1398
1399         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1400         ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1401
1402         /* Vertex fog: Rangefog is used */
1403         hr = IDirect3DDevice9_BeginScene(device);
1404         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP returned %#08x\n", hr);
1405         if (SUCCEEDED(hr))
1406         {
1407             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1408             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1409             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1410             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1411             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1412             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1413             hr = IDirect3DDevice9_EndScene(device);
1414             ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1415         }
1416         color = getPixelColor(device, 10, 10);
1417         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1418                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1419         color = getPixelColor(device, 630, 10);
1420         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1421                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1422         color = getPixelColor(device, 10, 470);
1423         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1424                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1425         color = getPixelColor(device, 630, 470);
1426         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1427                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1428
1429         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1430         ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1431
1432         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
1433         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1434     }
1435     else
1436     {
1437         skip("Range fog or table fog not supported, skipping range fog tests\n");
1438     }
1439
1440     /* Turn off the fog master switch to avoid confusing other tests */
1441     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1442     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1443     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1444     ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1445     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1446     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1447 }
1448
1449 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1450  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1451  * regardless of the actual addressing mode set. The way this test works is
1452  * that we sample in one of the corners of the cubemap with filtering enabled,
1453  * and check the interpolated color. There are essentially two reasonable
1454  * things an implementation can do: Either pick one of the faces and
1455  * interpolate the edge texel with itself (i.e., clamp within the face), or
1456  * interpolate between the edge texels of the three involved faces. It should
1457  * never involve the border color or the other side (texcoord wrapping) of a
1458  * face in the interpolation. */
1459 static void test_cube_wrap(IDirect3DDevice9 *device)
1460 {
1461     static const float quad[][6] = {
1462         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1463         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1464         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1465         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1466     };
1467
1468     static const D3DVERTEXELEMENT9 decl_elements[] = {
1469         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1470         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1471         D3DDECL_END()
1472     };
1473
1474     static const struct {
1475         D3DTEXTUREADDRESS mode;
1476         const char *name;
1477     } address_modes[] = {
1478         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1479         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1480         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1481         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1482         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1483     };
1484
1485     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1486     IDirect3DCubeTexture9 *texture = NULL;
1487     IDirect3DSurface9 *surface = NULL;
1488     IDirect3DSurface9 *face_surface;
1489     D3DLOCKED_RECT locked_rect;
1490     HRESULT hr;
1491     UINT x;
1492     INT y, face;
1493
1494     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1495     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1496     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1497     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1498
1499     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1500             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1501     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1502
1503     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1504             D3DPOOL_DEFAULT, &texture, NULL);
1505     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
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++ = 0xff0000ff;
1516         }
1517         for (x = 64; x < 128; ++x)
1518         {
1519             *ptr++ = 0xffff0000;
1520         }
1521     }
1522
1523     hr = IDirect3DSurface9_UnlockRect(surface);
1524     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1525
1526     hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1527     ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1528
1529     hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1530     ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1531
1532     IDirect3DSurface9_Release(face_surface);
1533
1534     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1535     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1536
1537     for (y = 0; y < 128; ++y)
1538     {
1539         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1540         for (x = 0; x < 64; ++x)
1541         {
1542             *ptr++ = 0xffff0000;
1543         }
1544         for (x = 64; x < 128; ++x)
1545         {
1546             *ptr++ = 0xff0000ff;
1547         }
1548     }
1549
1550     hr = IDirect3DSurface9_UnlockRect(surface);
1551     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1552
1553     /* Create cube faces */
1554     for (face = 1; face < 6; ++face)
1555     {
1556         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1557         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1558
1559         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1560         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1561
1562         IDirect3DSurface9_Release(face_surface);
1563     }
1564
1565     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1566     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1567
1568     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1569     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1570     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1571     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1572     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1573     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1574
1575     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1576     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1577
1578     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1579     {
1580         DWORD color;
1581
1582         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1583         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1584         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1585         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1586
1587         hr = IDirect3DDevice9_BeginScene(device);
1588         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1589
1590         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1591         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1592
1593         hr = IDirect3DDevice9_EndScene(device);
1594         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1595
1596         color = getPixelColor(device, 320, 240);
1597         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1598                 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1599                 color, address_modes[x].name);
1600
1601         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1602         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1603
1604         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1605         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1606     }
1607
1608     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1609     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1610
1611     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1612     IDirect3DCubeTexture9_Release(texture);
1613     IDirect3DSurface9_Release(surface);
1614 }
1615
1616 static void offscreen_test(IDirect3DDevice9 *device)
1617 {
1618     HRESULT hr;
1619     IDirect3DTexture9 *offscreenTexture = NULL;
1620     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1621     DWORD color;
1622
1623     static const float quad[][5] = {
1624         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1625         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1626         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1627         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1628     };
1629
1630     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1631     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1632
1633     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1634     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1635     if(!offscreenTexture) {
1636         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1637         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1638         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1639         if(!offscreenTexture) {
1640             skip("Cannot create an offscreen render target\n");
1641             goto out;
1642         }
1643     }
1644
1645     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1646     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1647     if(!backbuffer) {
1648         goto out;
1649     }
1650
1651     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1652     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1653     if(!offscreen) {
1654         goto out;
1655     }
1656
1657     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1658     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1659
1660     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1661     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1662     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1663     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1664     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1665     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1666     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1667     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1668     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1669     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1670
1671     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1672         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1673         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1674         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1675         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1676
1677         /* Draw without textures - Should result in a white quad */
1678         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1679         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1680
1681         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1682         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1683         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1684         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1685
1686         /* This time with the texture */
1687         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1688         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1689
1690         IDirect3DDevice9_EndScene(device);
1691     }
1692
1693     /* Center quad - should be white */
1694     color = getPixelColor(device, 320, 240);
1695     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1696     /* Some quad in the cleared part of the texture */
1697     color = getPixelColor(device, 170, 240);
1698     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1699     /* Part of the originally cleared back buffer */
1700     color = getPixelColor(device, 10, 10);
1701     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1702     if(0) {
1703         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1704          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1705          * the offscreen rendering mode this test would succeed or fail
1706          */
1707         color = getPixelColor(device, 10, 470);
1708         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1709     }
1710
1711     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1712
1713 out:
1714     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1715     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1716
1717     /* restore things */
1718     if (backbuffer)
1719     {
1720         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1721         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1722         IDirect3DSurface9_Release(backbuffer);
1723     }
1724     if(offscreenTexture) {
1725         IDirect3DTexture9_Release(offscreenTexture);
1726     }
1727     if(offscreen) {
1728         IDirect3DSurface9_Release(offscreen);
1729     }
1730 }
1731
1732 /* This test tests fog in combination with shaders.
1733  * What's tested: linear fog (vertex and table) with pixel shader
1734  *                linear table fog with non foggy vertex shader
1735  *                vertex fog with foggy vertex shader, non-linear
1736  *                fog with shader, non-linear fog with foggy shader,
1737  *                linear table fog with foggy shader
1738  */
1739 static void fog_with_shader_test(IDirect3DDevice9 *device)
1740 {
1741     HRESULT hr;
1742     DWORD color;
1743     union {
1744         float f;
1745         DWORD i;
1746     } start, end;
1747     unsigned int i, j;
1748
1749     /* basic vertex shader without fog computation ("non foggy") */
1750     static const DWORD vertex_shader_code1[] =
1751     {
1752         0xfffe0101,                                                             /* vs_1_1                       */
1753         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1754         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1755         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1756         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1757         0x0000ffff
1758     };
1759     /* basic vertex shader with reversed fog computation ("foggy") */
1760     static const DWORD vertex_shader_code2[] =
1761     {
1762         0xfffe0101,                                                             /* vs_1_1                        */
1763         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1764         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1765         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1766         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1767         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1768         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1769         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1770         0x0000ffff
1771     };
1772     /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
1773     static const DWORD vertex_shader_code3[] =
1774     {
1775         0xfffe0200,                                                             /* vs_2_0                        */
1776         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1777         0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1778         0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1779         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1780         0x02000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1781         0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1782         0x03000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1783         0x0000ffff
1784     };
1785     /* basic pixel shader */
1786     static const DWORD pixel_shader_code[] =
1787     {
1788         0xffff0101,                                                             /* ps_1_1     */
1789         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0 */
1790         0x0000ffff
1791     };
1792     static const DWORD pixel_shader_code2[] =
1793     {
1794         0xffff0200,                                                             /* ps_2_0     */
1795         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0 */
1796         0x02000001, 0x800f0800, 0x90e40000,                                     /* mov oC0, v0 */
1797         0x0000ffff
1798     };
1799
1800     static struct vertex quad[] = {
1801         {-1.0f, -1.0f,  0.0f,          0xffff0000  },
1802         {-1.0f,  1.0f,  0.0f,          0xffff0000  },
1803         { 1.0f, -1.0f,  0.0f,          0xffff0000  },
1804         { 1.0f,  1.0f,  0.0f,          0xffff0000  },
1805     };
1806
1807     static const D3DVERTEXELEMENT9 decl_elements[] = {
1808         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1809         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1810         D3DDECL_END()
1811     };
1812
1813     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1814     IDirect3DVertexShader9      *vertex_shader[4]   = {NULL, NULL, NULL, NULL};
1815     IDirect3DPixelShader9       *pixel_shader[3]    = {NULL, NULL, NULL};
1816
1817     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1818     static const struct test_data_t {
1819         int vshader;
1820         int pshader;
1821         D3DFOGMODE vfog;
1822         D3DFOGMODE tfog;
1823         unsigned int color[11];
1824     } test_data[] = {
1825         /* only pixel shader: */
1826         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1827         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1828         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1829         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1830         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1831         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1832         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1833         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1834         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1835         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1836         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1837         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1838         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1839         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1840         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1841
1842         /* vertex shader */
1843         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1844         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1845          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1846         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1847         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1848         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1849         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1850         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1851         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1852
1853         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1854         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1855         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1856         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1857         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1858         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1859
1860         /* vertex shader and pixel shader */
1861         /* The next 4 tests would read the fog coord output, but it isn't available.
1862          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1863          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1864          * These tests should be disabled if some other hardware behaves differently
1865          */
1866         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1867         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1868         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1869         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1870         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1871         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1872         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1873         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1874         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1875         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1876         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1877         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1878
1879         /* These use the Z coordinate with linear table fog */
1880         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1881         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1882         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1883         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1884         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1885         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1886         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1887         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1888         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1889         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1890         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1891         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1892
1893         /* Non-linear table fog without fog coord */
1894         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1895         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1896         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1897         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1898         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1899         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1900
1901         /* These tests fail on older Nvidia drivers */
1902         /* foggy vertex shader */
1903         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1904         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1905          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1906         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1907         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1908          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1909         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1910         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1911          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1912         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1913         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1914          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1915
1916         {3, 0, D3DFOG_NONE, D3DFOG_NONE,
1917         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1918          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1919         {3, 0, D3DFOG_EXP, D3DFOG_NONE,
1920         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1921          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1922         {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
1923         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1924          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1925         {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1926         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1927          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1928
1929         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1930          * all using the fixed fog-coord linear fog
1931          */
1932         /* vs_1_1 with ps_1_1 */
1933         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1934         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1935          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1936         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1937         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1938          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1939         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1940         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1941          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1942         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1943         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1944          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1945
1946         /* vs_2_0 with ps_1_1 */
1947         {3, 1, D3DFOG_NONE, D3DFOG_NONE,
1948         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1949          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1950         {3, 1, D3DFOG_EXP, D3DFOG_NONE,
1951         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1952          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1953         {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
1954         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1955          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1956         {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1957         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1958          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1959
1960         /* vs_1_1 with ps_2_0 */
1961         {2, 2, D3DFOG_NONE, D3DFOG_NONE,
1962         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1963          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1964         {2, 2, D3DFOG_EXP, D3DFOG_NONE,
1965         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1966          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1967         {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
1968         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1969          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1970         {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
1971         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1972          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1973
1974         /* vs_2_0 with ps_2_0 */
1975         {3, 2, D3DFOG_NONE, D3DFOG_NONE,
1976         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1977          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1978         {3, 2, D3DFOG_EXP, D3DFOG_NONE,
1979         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1980          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1981         {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
1982         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1983          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1984         {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
1985         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1986          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1987
1988         /* These use table fog. Here the shader-provided fog coordinate is
1989          * ignored and the z coordinate used instead
1990          */
1991         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1992         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1993         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1994         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1995         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1996         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1997         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1998         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1999         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2000     };
2001
2002     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
2003     start.f=0.1f;
2004     end.f=0.9f;
2005
2006     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
2007     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2008     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
2009     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2010     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
2011     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2012     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
2013     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2014     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
2015     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2016     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2017     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
2018
2019     /* Setup initial states: No lighting, fog on, fog color */
2020     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2021     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
2022     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
2023     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
2024     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
2025     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
2026     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2027     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2028
2029     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2030     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
2031     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2032     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
2033
2034     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
2035     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
2036     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
2037     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
2038     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
2039
2040     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
2041     {
2042         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
2043         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2044         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
2045         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2046         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
2047         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2048         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
2049         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2050
2051         for(j=0; j < 11; j++)
2052         {
2053             /* Don't use the whole zrange to prevent rounding errors */
2054             quad[0].z = 0.001f + (float)j / 10.02f;
2055             quad[1].z = 0.001f + (float)j / 10.02f;
2056             quad[2].z = 0.001f + (float)j / 10.02f;
2057             quad[3].z = 0.001f + (float)j / 10.02f;
2058
2059             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2060             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2061
2062             hr = IDirect3DDevice9_BeginScene(device);
2063             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
2064
2065             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2066             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2067
2068             hr = IDirect3DDevice9_EndScene(device);
2069             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
2070
2071             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
2072             color = getPixelColor(device, 128, 240);
2073             ok(color_match(color, test_data[i].color[j], 13),
2074                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
2075                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
2076
2077             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2078         }
2079     }
2080
2081     /* reset states */
2082     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2083     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2084     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2085     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2086     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2087     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2088     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
2089     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
2090
2091     IDirect3DVertexShader9_Release(vertex_shader[1]);
2092     IDirect3DVertexShader9_Release(vertex_shader[2]);
2093     IDirect3DVertexShader9_Release(vertex_shader[3]);
2094     IDirect3DPixelShader9_Release(pixel_shader[1]);
2095     IDirect3DPixelShader9_Release(pixel_shader[2]);
2096     IDirect3DVertexDeclaration9_Release(vertex_declaration);
2097 }
2098
2099 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
2100     unsigned int i, x, y;
2101     HRESULT hr;
2102     IDirect3DTexture9 *texture[2] = {NULL, NULL};
2103     D3DLOCKED_RECT locked_rect;
2104
2105     /* Generate the textures */
2106     for(i=0; i<2; i++)
2107     {
2108         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
2109                                             D3DPOOL_MANAGED, &texture[i], NULL);
2110         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
2111
2112         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
2113         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2114         for (y = 0; y < 128; ++y)
2115         {
2116             if(i)
2117             { /* Set up black texture with 2x2 texel white spot in the middle */
2118                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2119                 for (x = 0; x < 128; ++x)
2120                 {
2121                     if(y>62 && y<66 && x>62 && x<66)
2122                         *ptr++ = 0xffffffff;
2123                     else
2124                         *ptr++ = 0xff000000;
2125                 }
2126             }
2127             else
2128             { /* Set up a displacement map which points away from the center parallel to the closest axis.
2129                * (if multiplied with bumpenvmat)
2130               */
2131                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2132                 for (x = 0; x < 128; ++x)
2133                 {
2134                     if(abs(x-64)>abs(y-64))
2135                     {
2136                         if(x < 64)
2137                             *ptr++ = 0xc000;
2138                         else
2139                             *ptr++ = 0x4000;
2140                     }
2141                     else
2142                     {
2143                         if(y < 64)
2144                             *ptr++ = 0x0040;
2145                         else
2146                             *ptr++ = 0x00c0;
2147                     }
2148                 }
2149             }
2150         }
2151         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2152         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2153
2154         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2155         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2156
2157         /* Disable texture filtering */
2158         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2159         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2160         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2161         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2162
2163         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2164         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2165         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2166         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2167     }
2168 }
2169
2170 /* test the behavior of the texbem instruction
2171  * with normal 2D and projective 2D textures
2172  */
2173 static void texbem_test(IDirect3DDevice9 *device)
2174 {
2175     HRESULT hr;
2176     DWORD color;
2177     int i;
2178
2179     static const DWORD pixel_shader_code[] = {
2180         0xffff0101,                         /* ps_1_1*/
2181         0x00000042, 0xb00f0000,             /* tex t0*/
2182         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2183         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
2184         0x0000ffff
2185     };
2186     static const DWORD double_texbem_code[] =  {
2187         0xffff0103,                                         /* ps_1_3           */
2188         0x00000042, 0xb00f0000,                             /* tex t0           */
2189         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
2190         0x00000042, 0xb00f0002,                             /* tex t2           */
2191         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
2192         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
2193         0x0000ffff                                          /* end              */
2194     };
2195
2196
2197     static const float quad[][7] = {
2198         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
2199         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
2200         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
2201         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
2202     };
2203     static const float quad_proj[][9] = {
2204         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
2205         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
2206         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
2207         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
2208     };
2209
2210     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
2211         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2212         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2213         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2214         D3DDECL_END()
2215     },{
2216         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2217         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2218         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2219         D3DDECL_END()
2220     } };
2221
2222     /* use asymmetric matrix to test loading */
2223     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
2224
2225     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2226     IDirect3DPixelShader9       *pixel_shader       = NULL;
2227     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
2228     D3DLOCKED_RECT locked_rect;
2229
2230     generate_bumpmap_textures(device);
2231
2232     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2233     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2234     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2235     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2236     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
2237
2238     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2239     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2240
2241     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2242     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2243
2244     for(i=0; i<2; i++)
2245     {
2246         if(i)
2247         {
2248             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
2249             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2250         }
2251
2252         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
2253         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2254         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2255         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2256
2257         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
2258         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2259         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2260         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2261
2262         hr = IDirect3DDevice9_BeginScene(device);
2263         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2264
2265         if(!i)
2266             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2267         else
2268             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
2269         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2270
2271         hr = IDirect3DDevice9_EndScene(device);
2272         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2273
2274         color = getPixelColor(device, 320-32, 240);
2275         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2276         color = getPixelColor(device, 320+32, 240);
2277         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2278         color = getPixelColor(device, 320, 240-32);
2279         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2280         color = getPixelColor(device, 320, 240+32);
2281         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2282
2283         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2284         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2285
2286         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2287         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2288         IDirect3DPixelShader9_Release(pixel_shader);
2289
2290         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2291         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2292         IDirect3DVertexDeclaration9_Release(vertex_declaration);
2293     }
2294
2295     /* clean up */
2296     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2297     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2298
2299     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2300     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2301
2302     for(i=0; i<2; i++)
2303     {
2304         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
2305         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
2306         IDirect3DTexture9_Release(texture); /* For the GetTexture */
2307         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2308         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2309         IDirect3DTexture9_Release(texture);
2310     }
2311
2312     /* Test double texbem */
2313     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
2314     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2315     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
2316     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2317     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
2318     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2319     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
2320     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2321
2322     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
2323     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2324     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
2325     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
2326
2327     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2328     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2329
2330     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
2331     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2332     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
2333     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
2334     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
2335     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2336
2337     {
2338         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
2339 #define tex  0x00ff0000
2340 #define tex1 0x0000ff00
2341 #define origin 0x000000ff
2342         static const DWORD pixel_data[] = {
2343             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2344             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2345             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2346             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2347             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
2348             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2349             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2350             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2351         };
2352 #undef tex1
2353 #undef tex2
2354 #undef origin
2355
2356         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
2357         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2358         for(i = 0; i < 8; i++) {
2359             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
2360         }
2361         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
2362         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2363     }
2364
2365     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2366     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2367     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
2368     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2369     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
2370     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2371     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2372     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2373     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2374     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2375     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2376     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2377
2378     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
2379     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
2380     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2381     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2382     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2383     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2384     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2385     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2386     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2387     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2388
2389     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2390     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2391     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2392     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2393     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2394     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2395     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2396     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2397     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2398     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2399
2400     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2401     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2402     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2403     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2404     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2405     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2406     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2407     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2408     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2409     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2410     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2411     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2412     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2413     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2414     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2415     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2416
2417     hr = IDirect3DDevice9_BeginScene(device);
2418     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2419     if(SUCCEEDED(hr)) {
2420         static const float double_quad[] = {
2421             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2422              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2423             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2424              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2425         };
2426
2427         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2428         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2429         hr = IDirect3DDevice9_EndScene(device);
2430         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2431     }
2432     color = getPixelColor(device, 320, 240);
2433     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2434
2435     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2436     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2437     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2438     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2439     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2440     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2441     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2442     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2443     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2444     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2445
2446     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2447     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2448
2449     IDirect3DPixelShader9_Release(pixel_shader);
2450     IDirect3DTexture9_Release(texture);
2451     IDirect3DTexture9_Release(texture1);
2452     IDirect3DTexture9_Release(texture2);
2453 }
2454
2455 static void z_range_test(IDirect3DDevice9 *device)
2456 {
2457     const struct vertex quad[] =
2458     {
2459         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2460         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2461         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2462         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2463     };
2464     const struct vertex quad2[] =
2465     {
2466         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2467         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2468         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2469         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2470     };
2471
2472     const struct tvertex quad3[] =
2473     {
2474         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2475         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2476         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2477         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2478     };
2479     const struct tvertex quad4[] =
2480     {
2481         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2482         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2483         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2484         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2485     };
2486     HRESULT hr;
2487     DWORD color;
2488     IDirect3DVertexShader9 *shader;
2489     IDirect3DVertexDeclaration9 *decl;
2490     D3DCAPS9 caps;
2491     const DWORD shader_code[] = {
2492         0xfffe0101,                                     /* vs_1_1           */
2493         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2494         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2495         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2496         0x0000ffff                                      /* end              */
2497     };
2498     static const D3DVERTEXELEMENT9 decl_elements[] = {
2499         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2500         D3DDECL_END()
2501     };
2502
2503     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2504
2505     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2506      * then call Present. Then clear the color buffer to make sure it has some defined content
2507      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2508      * by the depth value.
2509      */
2510     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2511     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2512     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2513     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2514     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2515     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2516
2517     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2518     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2519     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2520     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2521     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2522     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2523     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2524     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2525     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2526     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2527
2528     hr = IDirect3DDevice9_BeginScene(device);
2529     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2530     if(hr == D3D_OK)
2531     {
2532         /* Test the untransformed vertex path */
2533         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2534         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2535         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2536         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2537         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2538         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2539
2540         /* Test the transformed vertex path */
2541         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2542         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2543
2544         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2545         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2546         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2547         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2548         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2549         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2550
2551         hr = IDirect3DDevice9_EndScene(device);
2552         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2553     }
2554
2555     /* Do not test the exact corner pixels, but go pretty close to them */
2556
2557     /* Clipped because z > 1.0 */
2558     color = getPixelColor(device, 28, 238);
2559     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2560     color = getPixelColor(device, 28, 241);
2561     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2562     {
2563         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2564     }
2565     else
2566     {
2567         ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2568     }
2569
2570     /* Not clipped, > z buffer clear value(0.75) */
2571     color = getPixelColor(device, 31, 238);
2572     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2573     color = getPixelColor(device, 31, 241);
2574     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2575     color = getPixelColor(device, 100, 238);
2576     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2577     color = getPixelColor(device, 100, 241);
2578     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2579
2580     /* Not clipped, < z buffer clear value */
2581     color = getPixelColor(device, 104, 238);
2582     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2583     color = getPixelColor(device, 104, 241);
2584     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2585     color = getPixelColor(device, 318, 238);
2586     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2587     color = getPixelColor(device, 318, 241);
2588     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2589
2590     /* Clipped because z < 0.0 */
2591     color = getPixelColor(device, 321, 238);
2592     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2593     color = getPixelColor(device, 321, 241);
2594     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2595     {
2596         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2597     }
2598     else
2599     {
2600         ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2601     }
2602
2603     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2604     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2605
2606     /* Test the shader path */
2607     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2608         skip("Vertex shaders not supported\n");
2609         goto out;
2610     }
2611     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2612     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2613     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2614     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2615
2616     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2617
2618     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2619     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2620     hr = IDirect3DDevice9_SetVertexShader(device, shader);
2621     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2622
2623     hr = IDirect3DDevice9_BeginScene(device);
2624     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2625     if(hr == D3D_OK)
2626     {
2627         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2628         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2629         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2630         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2631         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2632         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2633         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2634         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2635         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2636         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2637
2638         hr = IDirect3DDevice9_EndScene(device);
2639         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2640     }
2641
2642     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2643     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2644     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2645     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2646
2647     IDirect3DVertexDeclaration9_Release(decl);
2648     IDirect3DVertexShader9_Release(shader);
2649
2650     /* Z < 1.0 */
2651     color = getPixelColor(device, 28, 238);
2652     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2653
2654     /* 1.0 < z < 0.75 */
2655     color = getPixelColor(device, 31, 238);
2656     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2657     color = getPixelColor(device, 100, 238);
2658     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2659
2660     /* 0.75 < z < 0.0 */
2661     color = getPixelColor(device, 104, 238);
2662     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2663     color = getPixelColor(device, 318, 238);
2664     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2665
2666     /* 0.0 < z */
2667     color = getPixelColor(device, 321, 238);
2668     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2669
2670     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2671     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2672
2673     out:
2674     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2675     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2676     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2677     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2678     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2679     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2680 }
2681
2682 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2683 {
2684     D3DSURFACE_DESC desc;
2685     D3DLOCKED_RECT l;
2686     HRESULT hr;
2687     unsigned int x, y;
2688     DWORD *mem;
2689
2690     memset(&desc, 0, sizeof(desc));
2691     memset(&l, 0, sizeof(l));
2692     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2693     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2694     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2695     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2696     if(FAILED(hr)) return;
2697
2698     for(y = 0; y < desc.Height; y++)
2699     {
2700         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2701         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2702         {
2703             mem[x] = color;
2704         }
2705     }
2706     hr = IDirect3DSurface9_UnlockRect(surface);
2707     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2708 }
2709
2710 /* This tests a variety of possible StretchRect() situations */
2711 static void stretchrect_test(IDirect3DDevice9 *device)
2712 {
2713     HRESULT hr;
2714     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2715     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2716     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2717     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2718     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2719     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2720     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2721     IDirect3DSurface9 *orig_rt = NULL;
2722     IDirect3DSurface9 *backbuffer = NULL;
2723     DWORD color;
2724
2725     RECT src_rect64 = {0, 0, 64, 64};
2726     RECT src_rect64_flipy = {0, 64, 64, 0};
2727     RECT dst_rect64 = {0, 0, 64, 64};
2728     RECT dst_rect64_flipy = {0, 64, 64, 0};
2729
2730     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2731     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2732     if(!orig_rt) {
2733         goto out;
2734     }
2735
2736     /* Create our temporary surfaces in system memory */
2737     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2738     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2739     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2740     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2741
2742     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2743     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2744     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2745     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2746     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2747     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2748     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2749
2750     /* Create render target surfaces */
2751     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2752     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2753     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2754     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2755     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2756     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2757     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2758     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2759
2760     /* Create render target textures */
2761     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2762     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2763     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2764     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2765     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2766     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2767     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2768     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2769     if (tex_rt32) {
2770         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2771         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2772     }
2773     if (tex_rt64) {
2774         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2775         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2776     }
2777     if (tex_rt_dest64) {
2778         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2779         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2780     }
2781     if (tex_rt_dest640_480) {
2782         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2783         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2784     }
2785
2786     /* Create regular textures in D3DPOOL_DEFAULT */
2787     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2788     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2789     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2790     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2791     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2792     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2793     if (tex32) {
2794         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2795         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2796     }
2797     if (tex64) {
2798         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2799         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2800     }
2801     if (tex_dest64) {
2802         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2803         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2804     }
2805
2806     /*********************************************************************
2807      * Tests for when the source parameter is an offscreen plain surface *
2808      *********************************************************************/
2809
2810     /* Fill the offscreen 64x64 surface with green */
2811     if (surf_offscreen64)
2812         fill_surface(surf_offscreen64, 0xff00ff00);
2813
2814     /* offscreenplain ==> offscreenplain, same size */
2815     if(surf_offscreen64 && surf_offscreen_dest64) {
2816         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2817         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2818
2819         if (hr == D3D_OK) {
2820             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2821             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2822         }
2823
2824         /* Blit without scaling */
2825         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2826         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2827
2828         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2829         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2830         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2831
2832         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2833         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2834         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2835     }
2836
2837     /* offscreenplain ==> rendertarget texture, same size */
2838     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2839         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2840         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2841
2842         /* We can't lock rendertarget textures, so copy to our temp surface first */
2843         if (hr == D3D_OK) {
2844             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2845             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2846         }
2847
2848         if (hr == D3D_OK) {
2849             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2850             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2851         }
2852
2853         /* Blit without scaling */
2854         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2855         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2856
2857         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2858         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2859         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2860
2861         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2862         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2863         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2864     }
2865
2866     /* offscreenplain ==> rendertarget surface, same size */
2867     if(surf_offscreen64 && surf_rt_dest64) {
2868         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2869         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2870
2871         if (hr == D3D_OK) {
2872             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2873             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2874         }
2875
2876         /* Blit without scaling */
2877         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2878         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2879
2880         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2881         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2882         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2883
2884         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2885         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2886         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2887     }
2888
2889     /* offscreenplain ==> texture, same size (should fail) */
2890     if(surf_offscreen64 && surf_tex_dest64) {
2891         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2892         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2893     }
2894
2895     /* Fill the smaller offscreen surface with red */
2896     fill_surface(surf_offscreen32, 0xffff0000);
2897
2898     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2899     if(surf_offscreen32 && surf_offscreen64) {
2900         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2901         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2902     }
2903
2904     /* offscreenplain ==> rendertarget texture, scaling */
2905     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2906         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2907         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2908
2909         /* We can't lock rendertarget textures, so copy to our temp surface first */
2910         if (hr == D3D_OK) {
2911             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2912             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2913         }
2914
2915         if (hr == D3D_OK) {
2916             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2917             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2918         }
2919     }
2920
2921     /* offscreenplain ==> rendertarget surface, scaling */
2922     if(surf_offscreen32 && surf_rt_dest64) {
2923         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2924         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2925
2926         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2927         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2928     }
2929
2930     /* offscreenplain ==> texture, scaling (should fail) */
2931     if(surf_offscreen32 && surf_tex_dest64) {
2932         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2933         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2934     }
2935
2936     /************************************************************
2937      * Tests for when the source parameter is a regular texture *
2938      ************************************************************/
2939
2940     /* Fill the surface of the regular texture with blue */
2941     if (surf_tex64 && surf_temp64) {
2942         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2943         fill_surface(surf_temp64, 0xff0000ff);
2944         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2945         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2946     }
2947
2948     /* texture ==> offscreenplain, same size */
2949     if(surf_tex64 && surf_offscreen64) {
2950         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2951         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2952     }
2953
2954     /* texture ==> rendertarget texture, same size */
2955     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2956         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2957         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2958
2959         /* We can't lock rendertarget textures, so copy to our temp surface first */
2960         if (hr == D3D_OK) {
2961             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2962             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2963         }
2964
2965         if (hr == D3D_OK) {
2966             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2967             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2968         }
2969
2970         /* Blit without scaling */
2971         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2972         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2973
2974         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2975         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2976         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2977
2978         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2979         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2980         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2981     }
2982
2983     /* texture ==> rendertarget surface, same size */
2984     if(surf_tex64 && surf_rt_dest64) {
2985         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2986         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2987
2988         if (hr == D3D_OK) {
2989             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2990             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2991         }
2992
2993         /* Blit without scaling */
2994         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2995         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2996
2997         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2998         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2999         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3000
3001         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3002         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3003         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3004     }
3005
3006     /* texture ==> texture, same size (should fail) */
3007     if(surf_tex64 && surf_tex_dest64) {
3008         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
3009         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3010     }
3011
3012     /* Fill the surface of the smaller regular texture with red */
3013     if (surf_tex32 && surf_temp32) {
3014         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
3015         fill_surface(surf_temp32, 0xffff0000);
3016         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
3017         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3018     }
3019
3020     /* texture ==> offscreenplain, scaling (should fail) */
3021     if(surf_tex32 && surf_offscreen64) {
3022         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
3023         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3024     }
3025
3026     /* texture ==> rendertarget texture, scaling */
3027     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
3028         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
3029         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3030
3031         /* We can't lock rendertarget textures, so copy to our temp surface first */
3032         if (hr == D3D_OK) {
3033             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3034             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3035         }
3036
3037         if (hr == D3D_OK) {
3038             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3039             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3040         }
3041     }
3042
3043     /* texture ==> rendertarget surface, scaling */
3044     if(surf_tex32 && surf_rt_dest64) {
3045         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
3046         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3047
3048         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3049         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3050     }
3051
3052     /* texture ==> texture, scaling (should fail) */
3053     if(surf_tex32 && surf_tex_dest64) {
3054         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
3055         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3056     }
3057
3058     /*****************************************************************
3059      * Tests for when the source parameter is a rendertarget texture *
3060      *****************************************************************/
3061
3062     /* Fill the surface of the rendertarget texture with white */
3063     if (surf_tex_rt64 && surf_temp64) {
3064         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
3065         fill_surface(surf_temp64, 0xffffffff);
3066         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
3067         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3068     }
3069
3070     /* rendertarget texture ==> offscreenplain, same size */
3071     if(surf_tex_rt64 && surf_offscreen64) {
3072         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
3073         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3074     }
3075
3076     /* rendertarget texture ==> rendertarget texture, same size */
3077     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3078         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3079         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3080
3081         /* We can't lock rendertarget textures, so copy to our temp surface first */
3082         if (hr == D3D_OK) {
3083             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3084             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3085         }
3086
3087         if (hr == D3D_OK) {
3088             color = getPixelColorFromSurface(surf_temp64, 32, 32);
3089             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
3090         }
3091
3092         /* Blit without scaling */
3093         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3094         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3095
3096         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3097         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3098         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3099
3100         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3101         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3102         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3103     }
3104
3105     /* rendertarget texture ==> rendertarget surface, same size */
3106     if(surf_tex_rt64 && surf_rt_dest64) {
3107         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
3108         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3109
3110         if (hr == D3D_OK) {
3111             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3112             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
3113         }
3114
3115         /* Blit without scaling */
3116         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3117         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3118
3119         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3120         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
3121         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3122
3123         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3124         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3125         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3126     }
3127
3128     /* rendertarget texture ==> texture, same size (should fail) */
3129     if(surf_tex_rt64 && surf_tex_dest64) {
3130         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
3131         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3132     }
3133
3134     /* Fill the surface of the smaller rendertarget texture with red */
3135     if (surf_tex_rt32 && surf_temp32) {
3136         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
3137         fill_surface(surf_temp32, 0xffff0000);
3138         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3139         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3140     }
3141
3142     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
3143     if(surf_tex_rt32 && surf_offscreen64) {
3144         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
3145         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3146     }
3147
3148     /* rendertarget texture ==> rendertarget texture, scaling */
3149     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3150         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3151         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3152
3153         /* We can't lock rendertarget textures, so copy to our temp surface first */
3154         if (hr == D3D_OK) {
3155             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3156             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3157         }
3158
3159         if (hr == D3D_OK) {
3160             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3161             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3162         }
3163     }
3164
3165     /* rendertarget texture ==> rendertarget surface, scaling */
3166     if(surf_tex_rt32 && surf_rt_dest64) {
3167         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
3168         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3169
3170         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3171         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3172     }
3173
3174     /* rendertarget texture ==> texture, scaling (should fail) */
3175     if(surf_tex_rt32 && surf_tex_dest64) {
3176         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
3177         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3178     }
3179
3180     /*****************************************************************
3181      * Tests for when the source parameter is a rendertarget surface *
3182      *****************************************************************/
3183
3184     /* Fill the surface of the rendertarget surface with black */
3185     if (surf_rt64)
3186         fill_surface(surf_rt64, 0xff000000);
3187
3188     /* rendertarget texture ==> offscreenplain, same size */
3189     if(surf_rt64 && surf_offscreen64) {
3190         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
3191         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3192     }
3193
3194     /* rendertarget surface ==> rendertarget texture, same size */
3195     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3196         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3197         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3198
3199         /* We can't lock rendertarget textures, so copy to our temp surface first */
3200         if (hr == D3D_OK) {
3201             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3202             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3203         }
3204
3205         if (hr == D3D_OK) {
3206             color = getPixelColorFromSurface(surf_temp64, 32, 32);
3207             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3208         }
3209
3210         /* Blit without scaling */
3211         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3212         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3213
3214         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3215         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3216         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3217
3218         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3219         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3220         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3221     }
3222
3223     /* rendertarget surface ==> rendertarget surface, same size */
3224     if(surf_rt64 && surf_rt_dest64) {
3225         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
3226         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3227
3228         if (hr == D3D_OK) {
3229             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3230             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3231         }
3232
3233         /* Blit without scaling */
3234         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3235         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3236
3237         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3238         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
3239         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3240
3241         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3242         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3243         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3244     }
3245
3246     /* rendertarget surface ==> texture, same size (should fail) */
3247     if(surf_rt64 && surf_tex_dest64) {
3248         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
3249         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3250     }
3251
3252     /* Fill the surface of the smaller rendertarget texture with red */
3253     if (surf_rt32)
3254         fill_surface(surf_rt32, 0xffff0000);
3255
3256     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
3257     if(surf_rt32 && surf_offscreen64) {
3258         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
3259         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3260     }
3261
3262     /* rendertarget surface ==> rendertarget texture, scaling */
3263     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3264         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3265         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3266
3267         /* We can't lock rendertarget textures, so copy to our temp surface first */
3268         if (hr == D3D_OK) {
3269             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3270             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3271         }
3272
3273         if (hr == D3D_OK) {
3274             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3275             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3276         }
3277     }
3278
3279     /* rendertarget surface ==> rendertarget surface, scaling */
3280     if(surf_rt32 && surf_rt_dest64) {
3281         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
3282         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3283
3284         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3285         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3286     }
3287
3288     /* rendertarget surface ==> texture, scaling (should fail) */
3289     if(surf_rt32 && surf_tex_dest64) {
3290         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
3291         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3292     }
3293
3294     /* backbuffer ==> surface tests (no scaling) */
3295     if(backbuffer && surf_tex_rt_dest640_480)
3296     {
3297         RECT src_rect = {0, 0, 640, 480};
3298         RECT src_rect_flipy = {0, 480, 640, 0};
3299         RECT dst_rect = {0, 0, 640, 480};
3300         RECT dst_rect_flipy = {0, 480, 640, 0};
3301
3302         /* Blit with NULL rectangles */
3303         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
3304         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
3305
3306         /* Blit without scaling */
3307         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
3308         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3309
3310         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3311         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
3312         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3313
3314         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3315         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
3316         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3317     }
3318
3319     /* TODO: Test format conversions */
3320
3321
3322 out:
3323     /* Clean up */
3324     if (backbuffer)
3325         IDirect3DSurface9_Release(backbuffer);
3326     if (surf_rt32)
3327         IDirect3DSurface9_Release(surf_rt32);
3328     if (surf_rt64)
3329         IDirect3DSurface9_Release(surf_rt64);
3330     if (surf_rt_dest64)
3331         IDirect3DSurface9_Release(surf_rt_dest64);
3332     if (surf_temp32)
3333         IDirect3DSurface9_Release(surf_temp32);
3334     if (surf_temp64)
3335         IDirect3DSurface9_Release(surf_temp64);
3336     if (surf_offscreen32)
3337         IDirect3DSurface9_Release(surf_offscreen32);
3338     if (surf_offscreen64)
3339         IDirect3DSurface9_Release(surf_offscreen64);
3340     if (surf_offscreen_dest64)
3341         IDirect3DSurface9_Release(surf_offscreen_dest64);
3342
3343     if (tex_rt32) {
3344         if (surf_tex_rt32)
3345             IDirect3DSurface9_Release(surf_tex_rt32);
3346         IDirect3DTexture9_Release(tex_rt32);
3347     }
3348     if (tex_rt64) {
3349         if (surf_tex_rt64)
3350             IDirect3DSurface9_Release(surf_tex_rt64);
3351         IDirect3DTexture9_Release(tex_rt64);
3352     }
3353     if (tex_rt_dest64) {
3354         if (surf_tex_rt_dest64)
3355             IDirect3DSurface9_Release(surf_tex_rt_dest64);
3356         IDirect3DTexture9_Release(tex_rt_dest64);
3357     }
3358     if (tex_rt_dest640_480) {
3359         if (surf_tex_rt_dest640_480)
3360             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
3361         IDirect3DTexture9_Release(tex_rt_dest640_480);
3362     }
3363     if (tex32) {
3364         if (surf_tex32)
3365             IDirect3DSurface9_Release(surf_tex32);
3366         IDirect3DTexture9_Release(tex32);
3367     }
3368     if (tex64) {
3369         if (surf_tex64)
3370             IDirect3DSurface9_Release(surf_tex64);
3371         IDirect3DTexture9_Release(tex64);
3372     }
3373     if (tex_dest64) {
3374         if (surf_tex_dest64)
3375             IDirect3DSurface9_Release(surf_tex_dest64);
3376         IDirect3DTexture9_Release(tex_dest64);
3377     }
3378
3379     if (orig_rt) {
3380         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3381         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3382         IDirect3DSurface9_Release(orig_rt);
3383     }
3384 }
3385
3386 static void maxmip_test(IDirect3DDevice9 *device)
3387 {
3388     IDirect3DTexture9 *texture = NULL;
3389     IDirect3DSurface9 *surface = NULL;
3390     HRESULT hr;
3391     DWORD color;
3392     static const struct
3393     {
3394         struct
3395         {
3396             float x, y, z;
3397             float s, t;
3398         }
3399         v[4];
3400     }
3401     quads[] =
3402     {
3403         {{
3404             {-1.0, -1.0,  0.0,  0.0,  0.0},
3405             {-1.0,  0.0,  0.0,  0.0,  1.0},
3406             { 0.0, -1.0,  0.0,  1.0,  0.0},
3407             { 0.0,  0.0,  0.0,  1.0,  1.0},
3408         }},
3409         {{
3410             { 0.0, -1.0,  0.0,  0.0,  0.0},
3411             { 0.0,  0.0,  0.0,  0.0,  1.0},
3412             { 1.0, -1.0,  0.0,  1.0,  0.0},
3413             { 1.0,  0.0,  0.0,  1.0,  1.0},
3414         }},
3415         {{
3416             { 0.0,  0.0,  0.0,  0.0,  0.0},
3417             { 0.0,  1.0,  0.0,  0.0,  1.0},
3418             { 1.0,  0.0,  0.0,  1.0,  0.0},
3419             { 1.0,  1.0,  0.0,  1.0,  1.0},
3420         }},
3421         {{
3422             {-1.0,  0.0,  0.0,  0.0,  0.0},
3423             {-1.0,  1.0,  0.0,  0.0,  1.0},
3424             { 0.0,  0.0,  0.0,  1.0,  0.0},
3425             { 0.0,  1.0,  0.0,  1.0,  1.0},
3426         }},
3427     };
3428
3429     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3430                                         &texture, NULL);
3431     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3432     if(!texture)
3433     {
3434         skip("Failed to create test texture\n");
3435         return;
3436     }
3437
3438     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3439     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3440     fill_surface(surface, 0xffff0000);
3441     IDirect3DSurface9_Release(surface);
3442     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3443     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3444     fill_surface(surface, 0xff00ff00);
3445     IDirect3DSurface9_Release(surface);
3446     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3447     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3448     fill_surface(surface, 0xff0000ff);
3449     IDirect3DSurface9_Release(surface);
3450
3451     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3452     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3453     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3454     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3455
3456     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3457     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3458
3459     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3460     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3461
3462     hr = IDirect3DDevice9_BeginScene(device);
3463     if(SUCCEEDED(hr))
3464     {
3465         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3466         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3467         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3468         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3469
3470         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3471         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3472         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3473         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3474
3475         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3476         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3477         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3478         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3479
3480         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3481         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3482         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3483         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3484         hr = IDirect3DDevice9_EndScene(device);
3485         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3486     }
3487
3488     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3489     color = getPixelColor(device, 160, 360);
3490     ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3491     color = getPixelColor(device, 480, 360);
3492     ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3493     color = getPixelColor(device, 480, 120);
3494     ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3495     color = getPixelColor(device, 160, 120);
3496     ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3497     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3498     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3499
3500     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3501     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3502
3503     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3504     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3505
3506     hr = IDirect3DDevice9_BeginScene(device);
3507     if(SUCCEEDED(hr))
3508     {
3509         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3510         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3511         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3512         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3513
3514         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3515         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3516         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3517         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3518
3519         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3520         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3521         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3522         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3523
3524         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3525         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3526         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3527         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3528         hr = IDirect3DDevice9_EndScene(device);
3529         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3530     }
3531
3532     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3533      * level 3 (> levels in texture) samples from the highest level in the
3534      * texture (level 2). */
3535     color = getPixelColor(device, 160, 360);
3536     ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3537     color = getPixelColor(device, 480, 360);
3538     ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3539     color = getPixelColor(device, 480, 120);
3540     ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3541     color = getPixelColor(device, 160, 120);
3542     ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3543     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3544     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3545
3546     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3547     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3548
3549     hr = IDirect3DDevice9_BeginScene(device);
3550     if(SUCCEEDED(hr))
3551     {
3552         DWORD ret;
3553
3554         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3555         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3556         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3557         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3558         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3559         ret = IDirect3DTexture9_SetLOD(texture, 1);
3560         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3561         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3562         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3563
3564         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3565         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3566         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3567         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3568         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3569         ret = IDirect3DTexture9_SetLOD(texture, 2);
3570         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3571         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3572         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3573
3574         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3575         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3576         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3577         ret = IDirect3DTexture9_SetLOD(texture, 1);
3578         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3579         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3580         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3581
3582         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3583         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3584         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3585         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3586         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3587         ret = IDirect3DTexture9_SetLOD(texture, 1);
3588         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3589         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3590         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3591         hr = IDirect3DDevice9_EndScene(device);
3592         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3593     }
3594
3595     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3596      * level 3 (> levels in texture) samples from the highest level in the
3597      * texture (level 2). */
3598     color = getPixelColor(device, 160, 360);
3599     ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3600     color = getPixelColor(device, 480, 360);
3601     ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3602     color = getPixelColor(device, 480, 120);
3603     ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3604     color = getPixelColor(device, 160, 120);
3605     ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3606
3607     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3608     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3609
3610     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3611     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3612     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3613     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3614     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3615     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3616     IDirect3DTexture9_Release(texture);
3617 }
3618
3619 static void release_buffer_test(IDirect3DDevice9 *device)
3620 {
3621     IDirect3DVertexBuffer9 *vb = NULL;
3622     IDirect3DIndexBuffer9 *ib = NULL;
3623     HRESULT hr;
3624     BYTE *data;
3625     LONG ref;
3626
3627     static const struct vertex quad[] = {
3628         {-1.0,      -1.0,       0.1,        0xffff0000},
3629         {-1.0,       1.0,       0.1,        0xffff0000},
3630         { 1.0,       1.0,       0.1,        0xffff0000},
3631
3632         {-1.0,      -1.0,       0.1,        0xff00ff00},
3633         {-1.0,       1.0,       0.1,        0xff00ff00},
3634         { 1.0,       1.0,       0.1,        0xff00ff00}
3635     };
3636     short indices[] = {3, 4, 5};
3637
3638     /* Index and vertex buffers should always be creatable */
3639     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3640                                               D3DPOOL_MANAGED, &vb, NULL);
3641     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3642     if(!vb) {
3643         skip("Failed to create a vertex buffer\n");
3644         return;
3645     }
3646     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3647     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3648     if(!ib) {
3649         skip("Failed to create an index buffer\n");
3650         return;
3651     }
3652
3653     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3654     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3655     memcpy(data, quad, sizeof(quad));
3656     hr = IDirect3DVertexBuffer9_Unlock(vb);
3657     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3658
3659     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3660     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3661     memcpy(data, indices, sizeof(indices));
3662     hr = IDirect3DIndexBuffer9_Unlock(ib);
3663     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3664
3665     hr = IDirect3DDevice9_SetIndices(device, ib);
3666     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3667     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3668     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3669     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3670     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3671
3672     /* Now destroy the bound index buffer and draw again */
3673     ref = IDirect3DIndexBuffer9_Release(ib);
3674     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3675
3676     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3677     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3678
3679     hr = IDirect3DDevice9_BeginScene(device);
3680     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3681     if(SUCCEEDED(hr))
3682     {
3683         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3684          * making assumptions about the indices or vertices
3685          */
3686         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3687         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3688         hr = IDirect3DDevice9_EndScene(device);
3689         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3690     }
3691
3692     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3693     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3694
3695     hr = IDirect3DDevice9_SetIndices(device, NULL);
3696     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3697     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3698     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3699
3700     /* Index buffer was already destroyed as part of the test */
3701     IDirect3DVertexBuffer9_Release(vb);
3702 }
3703
3704 static void float_texture_test(IDirect3DDevice9 *device)
3705 {
3706     IDirect3D9 *d3d = NULL;
3707     HRESULT hr;
3708     IDirect3DTexture9 *texture = NULL;
3709     D3DLOCKED_RECT lr;
3710     float *data;
3711     DWORD color;
3712     float quad[] = {
3713         -1.0,      -1.0,       0.1,     0.0,    0.0,
3714         -1.0,       1.0,       0.1,     0.0,    1.0,
3715          1.0,      -1.0,       0.1,     1.0,    0.0,
3716          1.0,       1.0,       0.1,     1.0,    1.0,
3717     };
3718
3719     memset(&lr, 0, sizeof(lr));
3720     IDirect3DDevice9_GetDirect3D(device, &d3d);
3721     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3722                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3723         skip("D3DFMT_R32F textures not supported\n");
3724         goto out;
3725     }
3726
3727     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3728                                         D3DPOOL_MANAGED, &texture, NULL);
3729     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3730     if(!texture) {
3731         skip("Failed to create R32F texture\n");
3732         goto out;
3733     }
3734
3735     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3736     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3737     data = lr.pBits;
3738     *data = 0.0;
3739     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3740     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3741
3742     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3743     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3744
3745     hr = IDirect3DDevice9_BeginScene(device);
3746     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3747     if(SUCCEEDED(hr))
3748     {
3749         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3750         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3751
3752         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3753         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3754
3755         hr = IDirect3DDevice9_EndScene(device);
3756         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3757     }
3758     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3759     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3760
3761     color = getPixelColor(device, 240, 320);
3762     ok(color == 0x0000ffff, "R32F with value 0.0 has color %08x, expected 0x0000ffff\n", color);
3763
3764     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3765     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3766
3767 out:
3768     if(texture) IDirect3DTexture9_Release(texture);
3769     IDirect3D9_Release(d3d);
3770 }
3771
3772 static void g16r16_texture_test(IDirect3DDevice9 *device)
3773 {
3774     IDirect3D9 *d3d = NULL;
3775     HRESULT hr;
3776     IDirect3DTexture9 *texture = NULL;
3777     D3DLOCKED_RECT lr;
3778     DWORD *data;
3779     DWORD color;
3780     float quad[] = {
3781        -1.0,      -1.0,       0.1,     0.0,    0.0,
3782        -1.0,       1.0,       0.1,     0.0,    1.0,
3783         1.0,      -1.0,       0.1,     1.0,    0.0,
3784         1.0,       1.0,       0.1,     1.0,    1.0,
3785     };
3786
3787     memset(&lr, 0, sizeof(lr));
3788     IDirect3DDevice9_GetDirect3D(device, &d3d);
3789     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3790        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3791            skip("D3DFMT_G16R16 textures not supported\n");
3792            goto out;
3793     }
3794
3795     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3796                                         D3DPOOL_MANAGED, &texture, NULL);
3797     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3798     if(!texture) {
3799         skip("Failed to create D3DFMT_G16R16 texture\n");
3800         goto out;
3801     }
3802
3803     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3804     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3805     data = lr.pBits;
3806     *data = 0x0f00f000;
3807     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3808     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3809
3810     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3811     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3812
3813     hr = IDirect3DDevice9_BeginScene(device);
3814     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3815     if(SUCCEEDED(hr))
3816     {
3817         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3818         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3819
3820         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3821         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3822
3823         hr = IDirect3DDevice9_EndScene(device);
3824         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3825     }
3826     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3827     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3828
3829     color = getPixelColor(device, 240, 320);
3830     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3831        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3832
3833     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3834     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3835
3836 out:
3837     if(texture) IDirect3DTexture9_Release(texture);
3838     IDirect3D9_Release(d3d);
3839 }
3840
3841 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
3842 {
3843     LONG x_coords[2][2] =
3844     {
3845         {r.left - 1, r.left + 1},
3846         {r.right + 1, r.right - 1},
3847     };
3848     LONG y_coords[2][2] =
3849     {
3850         {r.top - 1, r.top + 1},
3851         {r.bottom + 1, r.bottom - 1}
3852     };
3853     unsigned int i, j, x_side, y_side;
3854
3855     for (i = 0; i < 2; ++i)
3856     {
3857         for (j = 0; j < 2; ++j)
3858         {
3859             for (x_side = 0; x_side < 2; ++x_side)
3860             {
3861                 for (y_side = 0; y_side < 2; ++y_side)
3862                 {
3863                     unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
3864                     DWORD color;
3865                     DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
3866
3867                     color = getPixelColor(device, x, y);
3868                     ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
3869                             message, x, y, color, expected);
3870                 }
3871             }
3872         }
3873     }
3874 }
3875
3876 struct projected_textures_test_run
3877 {
3878     const char *message;
3879     DWORD flags;
3880     IDirect3DVertexDeclaration9 *decl;
3881     BOOL vs, ps;
3882     RECT rect;
3883 };
3884
3885 static void projected_textures_test(IDirect3DDevice9 *device,
3886         struct projected_textures_test_run tests[4])
3887 {
3888     unsigned int i;
3889
3890     static const DWORD vertex_shader[] =
3891     {
3892         0xfffe0101,                                     /* vs_1_1           */
3893         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
3894         0x0000001f, 0x80000005, 0x900f0001,             /* dcl_texcoord0 v1 */
3895         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
3896         0x00000001, 0xe00f0000, 0x90e40001,             /* mov oT0, v1      */
3897         0x0000ffff                                      /* end              */
3898     };
3899     static const DWORD pixel_shader[] =
3900     {
3901         0xffff0103,                                     /* ps_1_3           */
3902         0x00000042, 0xb00f0000,                         /* tex t0           */
3903         0x00000001, 0x800f0000, 0xb0e40000,             /* mov r0, t0       */
3904         0x0000ffff                                      /* end              */
3905     };
3906     IDirect3DVertexShader9 *vs = NULL;
3907     IDirect3DPixelShader9 *ps = NULL;
3908     IDirect3D9 *d3d;
3909     D3DCAPS9 caps;
3910     HRESULT hr;
3911
3912     IDirect3DDevice9_GetDirect3D(device, &d3d);
3913     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3914     ok(SUCCEEDED(hr), "GetDeviceCaps failed (%08x)\n", hr);
3915     IDirect3D9_Release(d3d);
3916
3917     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
3918     {
3919         hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
3920         ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
3921     }
3922     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 3))
3923     {
3924         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
3925         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3926     }
3927
3928     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
3929     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3930
3931     hr = IDirect3DDevice9_BeginScene(device);
3932     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3933     if (FAILED(hr))
3934         return;
3935
3936     for (i = 0; i < 4; ++i)
3937     {
3938         DWORD value = 0xdeadbeef;
3939         static const float proj_quads[] =
3940         {
3941             -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3942              0.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3943             -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3944              0.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3945
3946              0.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3947              1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3948              0.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3949              1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3950
3951             -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3952              0.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3953             -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3954              0.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3955
3956              0.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3957              1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3958              0.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3959              1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3960         };
3961
3962         if (tests[i].vs)
3963         {
3964             if (!vs)
3965             {
3966                 skip("Vertex shaders not supported, skipping\n");
3967                 continue;
3968             }
3969             hr = IDirect3DDevice9_SetVertexShader(device, vs);
3970         }
3971         else
3972             hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3973         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
3974         if (tests[i].ps)
3975         {
3976             if (!ps)
3977             {
3978                 skip("Pixel shaders not supported, skipping\n");
3979                 continue;
3980             }
3981             hr = IDirect3DDevice9_SetPixelShader(device, ps);
3982         }
3983         else
3984             hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3985         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3986
3987         hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
3988         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3989
3990         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
3991         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3992         hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
3993         ok(SUCCEEDED(hr) && value == tests[i].flags,
3994                 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
3995
3996         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
3997                 &proj_quads[i * 4 * 7], 7 * sizeof(float));
3998         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3999     }
4000
4001     hr = IDirect3DDevice9_EndScene(device);
4002     ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4003
4004     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4005     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4006     if (vs) IDirect3DVertexShader9_Release(vs);
4007     if (ps) IDirect3DPixelShader9_Release(ps);
4008
4009     for (i = 0; i < 4; ++i)
4010     {
4011         if ((!tests[i].vs || vs) && (!tests[i].ps || ps))
4012             check_rect(device, tests[i].rect, tests[i].message);
4013     }
4014
4015     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4016     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4017 }
4018
4019 static void texture_transform_flags_test(IDirect3DDevice9 *device)
4020 {
4021     HRESULT hr;
4022     IDirect3D9 *d3d;
4023     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
4024     D3DCAPS9 caps;
4025     IDirect3DTexture9 *texture = NULL;
4026     IDirect3DVolumeTexture9 *volume = NULL;
4027     unsigned int x, y, z;
4028     D3DLOCKED_RECT lr;
4029     D3DLOCKED_BOX lb;
4030     DWORD color;
4031     UINT w, h;
4032     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
4033     float identity[16] = {1.0, 0.0, 0.0, 0.0,
4034                            0.0, 1.0, 0.0, 0.0,
4035                            0.0, 0.0, 1.0, 0.0,
4036                            0.0, 0.0, 0.0, 1.0};
4037     static const D3DVERTEXELEMENT9 decl_elements[] = {
4038         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4039         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4040         D3DDECL_END()
4041     };
4042     static const D3DVERTEXELEMENT9 decl_elements2[] = {
4043         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4044         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4045         D3DDECL_END()
4046     };
4047     static const D3DVERTEXELEMENT9 decl_elements3[] = {
4048         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4049         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4050         D3DDECL_END()
4051     };
4052     static const D3DVERTEXELEMENT9 decl_elements4[] = {
4053         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4054         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4055         D3DDECL_END()
4056     };
4057     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
4058                                                  0x00, 0xff, 0x00, 0x00,
4059                                                  0x00, 0x00, 0x00, 0x00,
4060                                                  0x00, 0x00, 0x00, 0x00};
4061
4062     memset(&lr, 0, sizeof(lr));
4063     memset(&lb, 0, sizeof(lb));
4064     IDirect3DDevice9_GetDirect3D(device, &d3d);
4065     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
4066                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
4067         fmt = D3DFMT_A16B16G16R16;
4068     }
4069     IDirect3D9_Release(d3d);
4070
4071     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4072     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4073     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4074     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4075     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
4076     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4077     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
4078     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4079     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
4080     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
4081     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
4082     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
4083     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
4084     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
4085     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4086     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
4087     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
4088     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
4089     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
4090     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
4091     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
4092     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
4093     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4094     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLOROP) returned %08x\n", hr);
4095     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4096     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLORARG1) returned %08x\n", hr);
4097     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4098     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
4099     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4100     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4101
4102     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4103     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
4104     w = min(1024, caps.MaxTextureWidth);
4105     h = min(1024, caps.MaxTextureHeight);
4106     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
4107                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
4108     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4109     if(!texture) {
4110         skip("Failed to create the test texture\n");
4111         return;
4112     }
4113
4114     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
4115      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
4116      * 1.0 in red and green for the x and y coords
4117      */
4118     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4119     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
4120     for(y = 0; y < h; y++) {
4121         for(x = 0; x < w; x++) {
4122             double r_f = (double) y / (double) h;
4123             double g_f = (double) x / (double) w;
4124             if(fmt == D3DFMT_A16B16G16R16) {
4125                 unsigned short r, g;
4126                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
4127                 r = (unsigned short) (r_f * 65536.0);
4128                 g = (unsigned short) (g_f * 65536.0);
4129                 dst[0] = r;
4130                 dst[1] = g;
4131                 dst[2] = 0;
4132                 dst[3] = 65535;
4133             } else {
4134                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
4135                 unsigned char r = (unsigned char) (r_f * 255.0);
4136                 unsigned char g = (unsigned char) (g_f * 255.0);
4137                 dst[0] = 0;
4138                 dst[1] = g;
4139                 dst[2] = r;
4140                 dst[3] = 255;
4141             }
4142         }
4143     }
4144     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4145     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4146     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4147     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4148
4149     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4150     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4151     hr = IDirect3DDevice9_BeginScene(device);
4152     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4153     if(SUCCEEDED(hr))
4154     {
4155         float quad1[] = {
4156             -1.0,      -1.0,       0.1,     1.0,    1.0,
4157             -1.0,       0.0,       0.1,     1.0,    1.0,
4158              0.0,      -1.0,       0.1,     1.0,    1.0,
4159              0.0,       0.0,       0.1,     1.0,    1.0,
4160         };
4161         float quad2[] = {
4162             -1.0,       0.0,       0.1,     1.0,    1.0,
4163             -1.0,       1.0,       0.1,     1.0,    1.0,
4164              0.0,       0.0,       0.1,     1.0,    1.0,
4165              0.0,       1.0,       0.1,     1.0,    1.0,
4166         };
4167         float quad3[] = {
4168              0.0,       0.0,       0.1,     0.5,    0.5,
4169              0.0,       1.0,       0.1,     0.5,    0.5,
4170              1.0,       0.0,       0.1,     0.5,    0.5,
4171              1.0,       1.0,       0.1,     0.5,    0.5,
4172         };
4173         float quad4[] = {
4174              320,       480,       0.1,     1.0,    0.0,    1.0,
4175              320,       240,       0.1,     1.0,    0.0,    1.0,
4176              640,       480,       0.1,     1.0,    0.0,    1.0,
4177              640,       240,       0.1,     1.0,    0.0,    1.0,
4178         };
4179         float mat[16] = {0.0, 0.0, 0.0, 0.0,
4180                           0.0, 0.0, 0.0, 0.0,
4181                           0.0, 0.0, 0.0, 0.0,
4182                           0.0, 0.0, 0.0, 0.0};
4183
4184         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4185         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4186         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4187         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4188         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4189
4190         /* What happens with transforms enabled? */
4191         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4192         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4193         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4194         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4195
4196         /* What happens if 4 coords are used, but only 2 given ?*/
4197         mat[8] = 1.0;
4198         mat[13] = 1.0;
4199         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4200         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4201         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4202         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4203         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4204         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4205
4206         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4207          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4208          * due to the coords in the vertices. (turns out red, indeed)
4209          */
4210         memset(mat, 0, sizeof(mat));
4211         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4212         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4213         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4214         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4215         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4216         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4217         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4218         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4219
4220         hr = IDirect3DDevice9_EndScene(device);
4221         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4222     }
4223     color = getPixelColor(device, 160, 360);
4224     ok(color_match(color, 0x00ffff00, 1), "quad 1 has color %08x, expected 0x00ffff00\n", color);
4225     color = getPixelColor(device, 160, 120);
4226     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4227     color = getPixelColor(device, 480, 120);
4228     ok(color_match(color, 0x0000ff00, 1), "quad 3 has color %08x, expected 0x0000ff00\n", color);
4229     color = getPixelColor(device, 480, 360);
4230     ok(color_match(color, 0x00ff0000, 1), "quad 4 has color %08x, expected 0x00ff0000\n", color);
4231     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4232     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4233
4234     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4235     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4236
4237     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4238     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4239     hr = IDirect3DDevice9_BeginScene(device);
4240     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4241     if(SUCCEEDED(hr))
4242     {
4243         float quad1[] = {
4244             -1.0,      -1.0,       0.1,     0.8,    0.2,
4245             -1.0,       0.0,       0.1,     0.8,    0.2,
4246              0.0,      -1.0,       0.1,     0.8,    0.2,
4247              0.0,       0.0,       0.1,     0.8,    0.2,
4248         };
4249         float quad2[] = {
4250             -1.0,       0.0,       0.1,     0.5,    1.0,
4251             -1.0,       1.0,       0.1,     0.5,    1.0,
4252              0.0,       0.0,       0.1,     0.5,    1.0,
4253              0.0,       1.0,       0.1,     0.5,    1.0,
4254         };
4255         float quad3[] = {
4256              0.0,       0.0,       0.1,     0.5,    1.0,
4257              0.0,       1.0,       0.1,     0.5,    1.0,
4258              1.0,       0.0,       0.1,     0.5,    1.0,
4259              1.0,       1.0,       0.1,     0.5,    1.0,
4260         };
4261         float quad4[] = {
4262              0.0,      -1.0,       0.1,     0.8,    0.2,
4263              0.0,       0.0,       0.1,     0.8,    0.2,
4264              1.0,      -1.0,       0.1,     0.8,    0.2,
4265              1.0,       0.0,       0.1,     0.8,    0.2,
4266         };
4267         float mat[16] = {0.0, 0.0, 0.0, 0.0,
4268                           0.0, 0.0, 0.0, 0.0,
4269                           0.0, 1.0, 0.0, 0.0,
4270                           0.0, 0.0, 0.0, 0.0};
4271
4272         /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
4273         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4274         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4275         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4276         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4277
4278         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4279         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4280
4281         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
4282          * it behaves like COUNT2 because normal textures require 2 coords. */
4283         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4284         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4285         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
4286         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4287
4288         /* Just to be sure, the same as quad2 above */
4289         memset(mat, 0, sizeof(mat));
4290         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4291         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4292         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4293         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4294         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4295         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4296
4297         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
4298          * used? And what happens to the first? */
4299         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4300         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4301         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4302         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4303
4304         hr = IDirect3DDevice9_EndScene(device);
4305         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4306     }
4307     color = getPixelColor(device, 160, 360);
4308     ok(color_match(color, 0x00ff0000, 1), "quad 1 has color %08x, expected 0x00ff0000\n", color);
4309     color = getPixelColor(device, 160, 120);
4310     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4311     color = getPixelColor(device, 480, 120);
4312     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
4313        "quad 3 has color %08x, expected 0x00ff8000\n", color);
4314     color = getPixelColor(device, 480, 360);
4315     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00ff0000, 1),
4316        "quad 4 has color %08x, expected 0x0033cc00\n", color);
4317     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4318     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4319
4320     IDirect3DTexture9_Release(texture);
4321
4322     /* Test projected textures, without any fancy matrices */
4323     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
4324     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4325     if (SUCCEEDED(hr))
4326     {
4327         struct projected_textures_test_run projected_tests_1[4] =
4328         {
4329             {
4330                 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
4331                 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
4332                 decl3,
4333                 FALSE, TRUE,
4334                 {120, 300, 240, 390},
4335             },
4336             {
4337                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
4338                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4339                 decl3,
4340                 FALSE, TRUE,
4341                 {400, 360, 480, 420},
4342             },
4343             /* Try with some invalid values */
4344             {
4345                 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
4346                 0xffffffff,
4347                 decl3,
4348                 FALSE, TRUE,
4349                 {120, 60, 240, 150}
4350             },
4351             {
4352                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
4353                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4354                 decl4,
4355                 FALSE, TRUE,
4356                 {340, 210, 360, 225},
4357             }
4358         };
4359         struct projected_textures_test_run projected_tests_2[4] =
4360         {
4361             {
4362                 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
4363                 D3DTTFF_PROJECTED,
4364                 decl3,
4365                 FALSE, TRUE,
4366                 {120, 300, 240, 390},
4367             },
4368             {
4369                 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
4370                 D3DTTFF_PROJECTED,
4371                 decl,
4372                 FALSE, TRUE,
4373                 {400, 360, 480, 420},
4374             },
4375             {
4376                 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
4377                 0xffffffff,
4378                 decl,
4379                 FALSE, TRUE,
4380                 {80, 120, 160, 180},
4381             },
4382             {
4383                 "D3DTTFF_COUNT1 (draws non-projected) - top right",
4384                 D3DTTFF_COUNT1,
4385                 decl4,
4386                 FALSE, TRUE,
4387                 {340, 210, 360, 225},
4388             }
4389         };
4390         struct projected_textures_test_run projected_tests_3[4] =
4391         {
4392             {
4393                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
4394                 D3DTTFF_PROJECTED,
4395                 decl3,
4396                 TRUE, FALSE,
4397                 {120, 300, 240, 390},
4398             },
4399             {
4400                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
4401                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4402                 decl3,
4403                 TRUE, TRUE,
4404                 {440, 300, 560, 390},
4405             },
4406             {
4407                 "0xffffffff (like COUNT4 | PROJECTED) - top left",
4408                 0xffffffff,
4409                 decl3,
4410                 TRUE, TRUE,
4411                 {120, 60, 240, 150},
4412             },
4413             {
4414                 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
4415                 D3DTTFF_PROJECTED,
4416                 decl3,
4417                 FALSE, FALSE,
4418                 {440, 60, 560, 150},
4419             },
4420         };
4421
4422         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4423         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4424
4425         hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4426         ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4427         for(x = 0; x < 4; x++) {
4428             memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
4429         }
4430         hr = IDirect3DTexture9_UnlockRect(texture, 0);
4431         ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4432         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4433         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4434
4435         projected_textures_test(device, projected_tests_1);
4436         projected_textures_test(device, projected_tests_2);
4437         projected_textures_test(device, projected_tests_3);
4438
4439         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4440         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4441         IDirect3DTexture9_Release(texture);
4442     }
4443
4444     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
4445     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4446     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
4447      * Thus watch out if sampling from texels between 0 and 1.
4448      */
4449     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
4450     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
4451        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
4452     if(!volume) {
4453         skip("Failed to create a volume texture\n");
4454         goto out;
4455     }
4456
4457     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
4458     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
4459     for(z = 0; z < 32; z++) {
4460         for(y = 0; y < 32; y++) {
4461             for(x = 0; x < 32; x++) {
4462                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
4463                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
4464                 float r_f = (float) x / 31.0;
4465                 float g_f = (float) y / 31.0;
4466                 float b_f = (float) z / 31.0;
4467
4468                 if(fmt == D3DFMT_A16B16G16R16) {
4469                     unsigned short *mem_s = mem;
4470                     mem_s[0]  = r_f * 65535.0;
4471                     mem_s[1]  = g_f * 65535.0;
4472                     mem_s[2]  = b_f * 65535.0;
4473                     mem_s[3]  = 65535;
4474                 } else {
4475                     unsigned char *mem_c = mem;
4476                     mem_c[0]  = b_f * 255.0;
4477                     mem_c[1]  = g_f * 255.0;
4478                     mem_c[2]  = r_f * 255.0;
4479                     mem_c[3]  = 255;
4480                 }
4481             }
4482         }
4483     }
4484     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
4485     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4486
4487     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
4488     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4489
4490     hr = IDirect3DDevice9_BeginScene(device);
4491     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4492     if(SUCCEEDED(hr))
4493     {
4494         float quad1[] = {
4495             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4496             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4497              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4498              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4499         };
4500         float quad2[] = {
4501             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4502             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
4503              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4504              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
4505         };
4506         float quad3[] = {
4507              0.0,       0.0,       0.1,     0.0,    0.0,
4508              0.0,       1.0,       0.1,     0.0,    0.0,
4509              1.0,       0.0,       0.1,     0.0,    0.0,
4510              1.0,       1.0,       0.1,     0.0,    0.0
4511         };
4512         float quad4[] = {
4513              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4514              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4515              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4516              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
4517         };
4518         float mat[16] = {1.0, 0.0, 0.0, 0.0,
4519                          0.0, 0.0, 1.0, 0.0,
4520                          0.0, 1.0, 0.0, 0.0,
4521                          0.0, 0.0, 0.0, 1.0};
4522         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4523         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4524
4525         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
4526          * values
4527          */
4528         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4529         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4530         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4531         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4532         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4533         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4534
4535         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
4536          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
4537          * otherwise the w will be missing(blue).
4538          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
4539          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
4540         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4541         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4542         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4543         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4544
4545         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
4546         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4547         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4548         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4549         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4550         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4551         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4552         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4553         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4554
4555         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4556          * disable. ATI extends it up to the amount of values needed for the volume texture
4557          */
4558         memset(mat, 0, sizeof(mat));
4559         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4560         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4561         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4562         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4563         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4564         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4565         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4566         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4567
4568         hr = IDirect3DDevice9_EndScene(device);
4569         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4570     }
4571
4572     color = getPixelColor(device, 160, 360);
4573     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4574     color = getPixelColor(device, 160, 120);
4575     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4576        "quad 2 has color %08x, expected 0x00ffff00\n", color);
4577     color = getPixelColor(device, 480, 120);
4578     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4579     color = getPixelColor(device, 480, 360);
4580     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4581
4582     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4583     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4584
4585     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4586     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4587     hr = IDirect3DDevice9_BeginScene(device);
4588     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4589     if(SUCCEEDED(hr))
4590     {
4591         float quad1[] = {
4592             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4593             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4594              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4595              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4596         };
4597         float quad2[] = {
4598             -1.0,       0.0,       0.1,
4599             -1.0,       1.0,       0.1,
4600              0.0,       0.0,       0.1,
4601              0.0,       1.0,       0.1,
4602         };
4603         float quad3[] = {
4604              0.0,       0.0,       0.1,     1.0,
4605              0.0,       1.0,       0.1,     1.0,
4606              1.0,       0.0,       0.1,     1.0,
4607              1.0,       1.0,       0.1,     1.0
4608         };
4609         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4610                            0.0, 0.0, 0.0, 0.0,
4611                            0.0, 0.0, 0.0, 0.0,
4612                            0.0, 1.0, 0.0, 0.0};
4613         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4614                            1.0, 0.0, 0.0, 0.0,
4615                            0.0, 1.0, 0.0, 0.0,
4616                            0.0, 0.0, 1.0, 0.0};
4617         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4618         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4619
4620         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4621          * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4622          * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4623          * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4624          * 4th *input* coordinate.
4625          */
4626         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4627         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4628         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4629         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4630         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4631         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4632
4633         /* None passed */
4634         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4635         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4636         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4637         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4638         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4639         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4640
4641         /* 4 used, 1 passed */
4642         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4643         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4644         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4645         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4646         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4647         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4648
4649         hr = IDirect3DDevice9_EndScene(device);
4650         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4651     }
4652     color = getPixelColor(device, 160, 360);
4653     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4654     color = getPixelColor(device, 160, 120);
4655     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4656     color = getPixelColor(device, 480, 120);
4657     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4658     /* Quad4: unused */
4659
4660     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4661     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4662
4663     IDirect3DVolumeTexture9_Release(volume);
4664
4665     out:
4666     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4667     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4668     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4669     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4670     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4671     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4672     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4673     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4674     IDirect3DVertexDeclaration9_Release(decl);
4675     IDirect3DVertexDeclaration9_Release(decl2);
4676     IDirect3DVertexDeclaration9_Release(decl3);
4677     IDirect3DVertexDeclaration9_Release(decl4);
4678 }
4679
4680 static void texdepth_test(IDirect3DDevice9 *device)
4681 {
4682     IDirect3DPixelShader9 *shader;
4683     HRESULT hr;
4684     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4685     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4686     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4687     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4688     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4689     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4690     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4691     DWORD shader_code[] = {
4692         0xffff0104,                                                                 /* ps_1_4               */
4693         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4694         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4695         0x0000fffd,                                                                 /* phase                */
4696         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4697         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4698         0x0000ffff                                                                  /* end                  */
4699     };
4700     DWORD color;
4701     float vertex[] = {
4702        -1.0,   -1.0,    0.0,
4703         1.0,   -1.0,    1.0,
4704        -1.0,    1.0,    0.0,
4705         1.0,    1.0,    1.0
4706     };
4707
4708     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4709     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4710
4711     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4712     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4713     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4714     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4715     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4716     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4717     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4718     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4719     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4720     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4721
4722     /* Fill the depth buffer with a gradient */
4723     hr = IDirect3DDevice9_BeginScene(device);
4724     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4725     if(SUCCEEDED(hr))
4726     {
4727         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4728         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4729         hr = IDirect3DDevice9_EndScene(device);
4730         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4731     }
4732
4733     /* Now perform the actual tests. Same geometry, but with the shader */
4734     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4735     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4736     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4737     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4738     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4739     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4740
4741     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4742     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4743     hr = IDirect3DDevice9_BeginScene(device);
4744     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4745     if(SUCCEEDED(hr))
4746     {
4747         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4748         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4749
4750         hr = IDirect3DDevice9_EndScene(device);
4751         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4752     }
4753
4754     color = getPixelColor(device, 158, 240);
4755     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4756     color = getPixelColor(device, 162, 240);
4757     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4758
4759     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4760     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4761
4762     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4763     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4764
4765     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4766     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4767     hr = IDirect3DDevice9_BeginScene(device);
4768     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4769     if(SUCCEEDED(hr))
4770     {
4771         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4772         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4773
4774         hr = IDirect3DDevice9_EndScene(device);
4775         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4776     }
4777
4778     color = getPixelColor(device, 318, 240);
4779     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4780     color = getPixelColor(device, 322, 240);
4781     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4782
4783     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4784     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4785
4786     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4787     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4788
4789     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4790     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4791     hr = IDirect3DDevice9_BeginScene(device);
4792     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4793     if(SUCCEEDED(hr))
4794     {
4795         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4796         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4797
4798         hr = IDirect3DDevice9_EndScene(device);
4799         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4800     }
4801
4802     color = getPixelColor(device, 1, 240);
4803     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4804
4805     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4806     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4807
4808     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4809     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4810
4811     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4812     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4813     hr = IDirect3DDevice9_BeginScene(device);
4814     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4815     if(SUCCEEDED(hr))
4816     {
4817         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4818         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4819
4820         hr = IDirect3DDevice9_EndScene(device);
4821         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4822     }
4823     color = getPixelColor(device, 318, 240);
4824     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4825     color = getPixelColor(device, 322, 240);
4826     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4827
4828     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4829     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4830
4831     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4832     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4833
4834     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4835     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4836     hr = IDirect3DDevice9_BeginScene(device);
4837     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4838     if(SUCCEEDED(hr))
4839     {
4840         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4841         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4842
4843         hr = IDirect3DDevice9_EndScene(device);
4844         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4845     }
4846
4847     color = getPixelColor(device, 1, 240);
4848     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4849
4850     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4851     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4852
4853     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4854     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4855
4856     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4857     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4858     hr = IDirect3DDevice9_BeginScene(device);
4859     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4860     if(SUCCEEDED(hr))
4861     {
4862         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4863         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4864
4865         hr = IDirect3DDevice9_EndScene(device);
4866         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4867     }
4868
4869     color = getPixelColor(device, 638, 240);
4870     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4871
4872     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4873     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4874
4875     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4876     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4877
4878     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4879     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4880     hr = IDirect3DDevice9_BeginScene(device);
4881     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4882     if(SUCCEEDED(hr))
4883     {
4884         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4885         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4886
4887         hr = IDirect3DDevice9_EndScene(device);
4888         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4889     }
4890
4891     color = getPixelColor(device, 638, 240);
4892     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4893
4894     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4895     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4896
4897     /* Cleanup */
4898     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4899     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4900     IDirect3DPixelShader9_Release(shader);
4901
4902     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4903     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4904     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4905     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4906 }
4907
4908 static void texkill_test(IDirect3DDevice9 *device)
4909 {
4910     IDirect3DPixelShader9 *shader;
4911     HRESULT hr;
4912     DWORD color;
4913
4914     const float vertex[] = {
4915     /*                          bottom  top    right    left */
4916         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4917          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4918         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4919          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4920     };
4921
4922     DWORD shader_code_11[] = {
4923     0xffff0101,                                                             /* ps_1_1                     */
4924     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4925     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4926     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4927     0x0000ffff                                                              /* end                        */
4928     };
4929     DWORD shader_code_20[] = {
4930     0xffff0200,                                                             /* ps_2_0                     */
4931     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4932     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4933     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4934     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4935     0x0000ffff                                                              /* end                        */
4936     };
4937
4938     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4939     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4940     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4941     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4942
4943     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4944     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4945     hr = IDirect3DDevice9_BeginScene(device);
4946     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4947     if(SUCCEEDED(hr))
4948     {
4949         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4950         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4951         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4952         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4953         hr = IDirect3DDevice9_EndScene(device);
4954         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4955     }
4956     color = getPixelColor(device, 63, 46);
4957     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4958     color = getPixelColor(device, 66, 46);
4959     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4960     color = getPixelColor(device, 63, 49);
4961     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4962     color = getPixelColor(device, 66, 49);
4963     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4964
4965     color = getPixelColor(device, 578, 46);
4966     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4967     color = getPixelColor(device, 575, 46);
4968     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4969     color = getPixelColor(device, 578, 49);
4970     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4971     color = getPixelColor(device, 575, 49);
4972     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4973
4974     color = getPixelColor(device, 63, 430);
4975     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4976     color = getPixelColor(device, 63, 433);
4977     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4978     color = getPixelColor(device, 66, 433);
4979     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4980     color = getPixelColor(device, 66, 430);
4981     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4982
4983     color = getPixelColor(device, 578, 430);
4984     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4985     color = getPixelColor(device, 578, 433);
4986     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4987     color = getPixelColor(device, 575, 433);
4988     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4989     color = getPixelColor(device, 575, 430);
4990     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4991
4992     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4993     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4994
4995     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4996     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4997     IDirect3DPixelShader9_Release(shader);
4998
4999     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5000     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5001     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
5002     if(FAILED(hr)) {
5003         skip("Failed to create 2.0 test shader, most likely not supported\n");
5004         return;
5005     }
5006
5007     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5008     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5009     hr = IDirect3DDevice9_BeginScene(device);
5010     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5011     if(SUCCEEDED(hr))
5012     {
5013         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5014         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5015         hr = IDirect3DDevice9_EndScene(device);
5016         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5017     }
5018
5019     color = getPixelColor(device, 63, 46);
5020     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
5021     color = getPixelColor(device, 66, 46);
5022     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
5023     color = getPixelColor(device, 63, 49);
5024     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
5025     color = getPixelColor(device, 66, 49);
5026     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
5027
5028     color = getPixelColor(device, 578, 46);
5029     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5030     color = getPixelColor(device, 575, 46);
5031     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5032     color = getPixelColor(device, 578, 49);
5033     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5034     color = getPixelColor(device, 575, 49);
5035     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5036
5037     color = getPixelColor(device, 63, 430);
5038     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5039     color = getPixelColor(device, 63, 433);
5040     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5041     color = getPixelColor(device, 66, 433);
5042     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5043     color = getPixelColor(device, 66, 430);
5044     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5045
5046     color = getPixelColor(device, 578, 430);
5047     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5048     color = getPixelColor(device, 578, 433);
5049     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5050     color = getPixelColor(device, 575, 433);
5051     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5052     color = getPixelColor(device, 575, 430);
5053     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5054
5055     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5056     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5057
5058     /* Cleanup */
5059     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5060     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
5061     IDirect3DPixelShader9_Release(shader);
5062 }
5063
5064 static void x8l8v8u8_test(IDirect3DDevice9 *device)
5065 {
5066     IDirect3D9 *d3d9;
5067     HRESULT hr;
5068     IDirect3DTexture9 *texture;
5069     IDirect3DPixelShader9 *shader;
5070     IDirect3DPixelShader9 *shader2;
5071     D3DLOCKED_RECT lr;
5072     DWORD color;
5073     DWORD shader_code[] = {
5074         0xffff0101,                             /* ps_1_1       */
5075         0x00000042, 0xb00f0000,                 /* tex t0       */
5076         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
5077         0x0000ffff                              /* end          */
5078     };
5079     DWORD shader_code2[] = {
5080         0xffff0101,                             /* ps_1_1       */
5081         0x00000042, 0xb00f0000,                 /* tex t0       */
5082         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
5083         0x0000ffff                              /* end          */
5084     };
5085
5086     float quad[] = {
5087        -1.0,   -1.0,   0.1,     0.5,    0.5,
5088         1.0,   -1.0,   0.1,     0.5,    0.5,
5089        -1.0,    1.0,   0.1,     0.5,    0.5,
5090         1.0,    1.0,   0.1,     0.5,    0.5,
5091     };
5092
5093     memset(&lr, 0, sizeof(lr));
5094     IDirect3DDevice9_GetDirect3D(device, &d3d9);
5095     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5096                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
5097     IDirect3D9_Release(d3d9);
5098     if(FAILED(hr)) {
5099         skip("No D3DFMT_X8L8V8U8 support\n");
5100         return;
5101     };
5102
5103     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5104     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5105
5106     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
5107     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
5108     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5109     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
5110     *((DWORD *) lr.pBits) = 0x11ca3141;
5111     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5112     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
5113
5114     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5115     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5116     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
5117     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5118
5119     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5120     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5121     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5122     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5123     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5124     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5125
5126     hr = IDirect3DDevice9_BeginScene(device);
5127     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5128     if(SUCCEEDED(hr))
5129     {
5130         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5131         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5132
5133         hr = IDirect3DDevice9_EndScene(device);
5134         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5135     }
5136     color = getPixelColor(device, 578, 430);
5137     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
5138        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
5139     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5140     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5141
5142     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
5143     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5144     hr = IDirect3DDevice9_BeginScene(device);
5145     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5146     if(SUCCEEDED(hr))
5147     {
5148         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5149         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5150
5151         hr = IDirect3DDevice9_EndScene(device);
5152         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5153     }
5154     color = getPixelColor(device, 578, 430);
5155     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
5156     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5157     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5158
5159     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5160     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5161     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5162     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5163     IDirect3DPixelShader9_Release(shader);
5164     IDirect3DPixelShader9_Release(shader2);
5165     IDirect3DTexture9_Release(texture);
5166 }
5167
5168 static void autogen_mipmap_test(IDirect3DDevice9 *device)
5169 {
5170     HRESULT hr;
5171     IDirect3D9 *d3d;
5172     IDirect3DTexture9 *texture = NULL;
5173     IDirect3DSurface9 *surface;
5174     DWORD color;
5175     const RECT r1 = {256, 256, 512, 512};
5176     const RECT r2 = {512, 256, 768, 512};
5177     const RECT r3 = {256, 512, 512, 768};
5178     const RECT r4 = {512, 512, 768, 768};
5179     unsigned int x, y;
5180     D3DLOCKED_RECT lr;
5181     memset(&lr, 0, sizeof(lr));
5182
5183     IDirect3DDevice9_GetDirect3D(device, &d3d);
5184     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5185        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
5186         skip("No autogenmipmap support\n");
5187         IDirect3D9_Release(d3d);
5188         return;
5189     }
5190     IDirect3D9_Release(d3d);
5191
5192     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5193     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5194
5195     /* Make the mipmap big, so that a smaller mipmap is used
5196      */
5197     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5198                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5199     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5200
5201     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5202     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5203     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5204     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5205     for(y = 0; y < 1024; y++) {
5206         for(x = 0; x < 1024; x++) {
5207             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5208             POINT pt;
5209
5210             pt.x = x;
5211             pt.y = y;
5212             if(PtInRect(&r1, pt)) {
5213                 *dst = 0xffff0000;
5214             } else if(PtInRect(&r2, pt)) {
5215                 *dst = 0xff00ff00;
5216             } else if(PtInRect(&r3, pt)) {
5217                 *dst = 0xff0000ff;
5218             } else if(PtInRect(&r4, pt)) {
5219                 *dst = 0xff000000;
5220             } else {
5221                 *dst = 0xffffffff;
5222             }
5223         }
5224     }
5225     hr = IDirect3DSurface9_UnlockRect(surface);
5226     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5227     IDirect3DSurface9_Release(surface);
5228
5229     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5230     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5231     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5232     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5233
5234     hr = IDirect3DDevice9_BeginScene(device);
5235     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5236     if(SUCCEEDED(hr)) {
5237         const float quad[] =  {
5238            -0.5,   -0.5,    0.1,    0.0,    0.0,
5239            -0.5,    0.5,    0.1,    0.0,    1.0,
5240             0.5,   -0.5,    0.1,    1.0,    0.0,
5241             0.5,    0.5,    0.1,    1.0,    1.0
5242         };
5243
5244         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5245         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5246         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5247         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5248         hr = IDirect3DDevice9_EndScene(device);
5249         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5250     }
5251     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5252     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5253     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
5254     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5255     IDirect3DTexture9_Release(texture);
5256
5257     color = getPixelColor(device, 200, 200);
5258     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5259     color = getPixelColor(device, 280, 200);
5260     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5261     color = getPixelColor(device, 360, 200);
5262     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5263     color = getPixelColor(device, 440, 200);
5264     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5265     color = getPixelColor(device, 200, 270);
5266     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5267     color = getPixelColor(device, 280, 270);
5268     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5269     color = getPixelColor(device, 360, 270);
5270     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5271     color = getPixelColor(device, 440, 270);
5272     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5273     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5274     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5275 }
5276
5277 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
5278 {
5279     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5280     IDirect3DVertexDeclaration9 *decl;
5281     HRESULT hr;
5282     DWORD color;
5283     DWORD shader_code_11[] =  {
5284         0xfffe0101,                                         /* vs_1_1           */
5285         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5286         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5287         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5288         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5289         0x0000ffff                                          /* end              */
5290     };
5291     DWORD shader_code_11_2[] =  {
5292         0xfffe0101,                                         /* vs_1_1           */
5293         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
5294         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
5295         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5296         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5297         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5298         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5299         0x0000ffff                                          /* end              */
5300     };
5301     DWORD shader_code_20[] =  {
5302         0xfffe0200,                                         /* vs_2_0           */
5303         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5304         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5305         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5306         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5307         0x0000ffff                                          /* end              */
5308     };
5309     DWORD shader_code_20_2[] =  {
5310         0xfffe0200,                                         /* vs_2_0           */
5311         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
5312         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
5313         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5314         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5315         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5316         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5317         0x0000ffff                                          /* end              */
5318     };
5319     static const D3DVERTEXELEMENT9 decl_elements[] = {
5320         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5321         D3DDECL_END()
5322     };
5323     float quad1[] = {
5324         -1.0,   -1.0,   0.1,
5325          0.0,   -1.0,   0.1,
5326         -1.0,    0.0,   0.1,
5327          0.0,    0.0,   0.1
5328     };
5329     float quad2[] = {
5330          0.0,   -1.0,   0.1,
5331          1.0,   -1.0,   0.1,
5332          0.0,    0.0,   0.1,
5333          1.0,    0.0,   0.1
5334     };
5335     float quad3[] = {
5336          0.0,    0.0,   0.1,
5337          1.0,    0.0,   0.1,
5338          0.0,    1.0,   0.1,
5339          1.0,    1.0,   0.1
5340     };
5341     float quad4[] = {
5342         -1.0,    0.0,   0.1,
5343          0.0,    0.0,   0.1,
5344         -1.0,    1.0,   0.1,
5345          0.0,    1.0,   0.1
5346     };
5347     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
5348     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
5349
5350     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5351     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5352
5353     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
5354     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5355     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
5356     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5357     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
5358     if(FAILED(hr)) shader_20 = NULL;
5359     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
5360     if(FAILED(hr)) shader_20_2 = NULL;
5361     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5362     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5363
5364     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
5365     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5366     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
5367     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5368     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5369     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5370
5371     hr = IDirect3DDevice9_BeginScene(device);
5372     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5373     if(SUCCEEDED(hr))
5374     {
5375         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
5376         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5377         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5378         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5379
5380         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
5381         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5382         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5383         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5384
5385         if(shader_20) {
5386             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
5387             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5388             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5389             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5390         }
5391
5392         if(shader_20_2) {
5393             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
5394             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5395             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5396             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5397         }
5398
5399         hr = IDirect3DDevice9_EndScene(device);
5400         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5401     }
5402
5403     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5404     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5405     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5406     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5407
5408     color = getPixelColor(device, 160, 360);
5409     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5410        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
5411     color = getPixelColor(device, 480, 360);
5412     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5413        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
5414     if(shader_20) {
5415         color = getPixelColor(device, 480, 120);
5416         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5417            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
5418     }
5419     if(shader_20_2) {
5420         color = getPixelColor(device, 160, 120);
5421         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5422            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5423     }
5424     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5425     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5426
5427     IDirect3DVertexDeclaration9_Release(decl);
5428     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
5429     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
5430     IDirect3DVertexShader9_Release(shader_11_2);
5431     IDirect3DVertexShader9_Release(shader_11);
5432 }
5433
5434 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
5435 {
5436     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
5437     HRESULT hr;
5438     DWORD color;
5439     DWORD shader_code_11[] =  {
5440         0xffff0101,                                         /* ps_1_1           */
5441         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5442         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5443         0x0000ffff                                          /* end              */
5444     };
5445     DWORD shader_code_12[] =  {
5446         0xffff0102,                                         /* ps_1_2           */
5447         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5448         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5449         0x0000ffff                                          /* end              */
5450     };
5451     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
5452      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
5453      * During development of this test, 1.3 shaders were verified too
5454      */
5455     DWORD shader_code_14[] =  {
5456         0xffff0104,                                         /* ps_1_4           */
5457         /* Try to make one constant local. It gets clamped too, although the binary contains
5458          * the bigger numbers
5459          */
5460         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
5461         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5462         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5463         0x0000ffff                                          /* end              */
5464     };
5465     DWORD shader_code_20[] =  {
5466         0xffff0200,                                         /* ps_2_0           */
5467         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5468         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5469         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
5470         0x0000ffff                                          /* end              */
5471     };
5472     float quad1[] = {
5473         -1.0,   -1.0,   0.1,
5474          0.0,   -1.0,   0.1,
5475         -1.0,    0.0,   0.1,
5476          0.0,    0.0,   0.1
5477     };
5478     float quad2[] = {
5479          0.0,   -1.0,   0.1,
5480          1.0,   -1.0,   0.1,
5481          0.0,    0.0,   0.1,
5482          1.0,    0.0,   0.1
5483     };
5484     float quad3[] = {
5485          0.0,    0.0,   0.1,
5486          1.0,    0.0,   0.1,
5487          0.0,    1.0,   0.1,
5488          1.0,    1.0,   0.1
5489     };
5490     float quad4[] = {
5491         -1.0,    0.0,   0.1,
5492          0.0,    0.0,   0.1,
5493         -1.0,    1.0,   0.1,
5494          0.0,    1.0,   0.1
5495     };
5496     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
5497     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
5498
5499     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5500     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5501
5502     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5503     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5504     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5505     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5506     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5507     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5508     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
5509     if(FAILED(hr)) shader_20 = NULL;
5510
5511     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5512     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5513     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5514     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5515     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5516     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5517
5518     hr = IDirect3DDevice9_BeginScene(device);
5519     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5520     if(SUCCEEDED(hr))
5521     {
5522         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5523         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5524         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5525         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5526
5527         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5528         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5529         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5530         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5531
5532         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5533         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5534         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5535         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5536
5537         if(shader_20) {
5538             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
5539             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5540             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5541             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5542         }
5543
5544         hr = IDirect3DDevice9_EndScene(device);
5545         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5546     }
5547     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5548     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5549
5550     color = getPixelColor(device, 160, 360);
5551     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5552        "quad 1 has color %08x, expected 0x00808000\n", color);
5553     color = getPixelColor(device, 480, 360);
5554     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5555        "quad 2 has color %08x, expected 0x00808000\n", color);
5556     color = getPixelColor(device, 480, 120);
5557     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5558        "quad 3 has color %08x, expected 0x00808000\n", color);
5559     if(shader_20) {
5560         color = getPixelColor(device, 160, 120);
5561         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5562            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5563     }
5564     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5565     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5566
5567     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5568     IDirect3DPixelShader9_Release(shader_14);
5569     IDirect3DPixelShader9_Release(shader_12);
5570     IDirect3DPixelShader9_Release(shader_11);
5571 }
5572
5573 static void dp2add_ps_test(IDirect3DDevice9 *device)
5574 {
5575     IDirect3DPixelShader9 *shader_dp2add = NULL;
5576     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5577     HRESULT hr;
5578     DWORD color;
5579
5580     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
5581      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5582      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
5583      * r0 first.
5584      * The result here for the r,g,b components should be roughly 0.5:
5585      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5586     static const DWORD shader_code_dp2add[] =  {
5587         0xffff0200,                                                             /* ps_2_0                       */
5588         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
5589
5590         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5591         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
5592
5593         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
5594         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5595         0x0000ffff                                                              /* end                          */
5596     };
5597
5598     /* Test the _sat modifier, too.  Result here should be:
5599      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5600      *      _SAT: ==> 1.0
5601      *   ADD: (1.0 + -0.5) = 0.5
5602      */
5603     static const DWORD shader_code_dp2add_sat[] =  {
5604         0xffff0200,                                                             /* ps_2_0                           */
5605         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
5606
5607         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
5608         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
5609         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5610
5611         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5612         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5613         0x0000ffff                                                              /* end                              */
5614     };
5615
5616     const float quad[] = {
5617         -1.0,   -1.0,   0.1,
5618          1.0,   -1.0,   0.1,
5619         -1.0,    1.0,   0.1,
5620          1.0,    1.0,   0.1
5621     };
5622
5623
5624     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5625     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5626
5627     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5628     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5629
5630     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5631     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5632
5633     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5634     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5635
5636     if (shader_dp2add) {
5637
5638         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5639         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5640
5641         hr = IDirect3DDevice9_BeginScene(device);
5642         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5643         if(SUCCEEDED(hr))
5644         {
5645             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5646             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5647
5648             hr = IDirect3DDevice9_EndScene(device);
5649             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5650         }
5651
5652         color = getPixelColor(device, 360, 240);
5653         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5654                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5655
5656         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5657         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5658
5659         IDirect3DPixelShader9_Release(shader_dp2add);
5660     } else {
5661         skip("dp2add shader creation failed\n");
5662     }
5663
5664     if (shader_dp2add_sat) {
5665
5666         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5667         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5668
5669         hr = IDirect3DDevice9_BeginScene(device);
5670         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5671         if(SUCCEEDED(hr))
5672         {
5673             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5674             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5675
5676             hr = IDirect3DDevice9_EndScene(device);
5677             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5678         }
5679
5680         color = getPixelColor(device, 360, 240);
5681         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5682                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5683
5684         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5685         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5686
5687         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5688     } else {
5689         skip("dp2add shader creation failed\n");
5690     }
5691
5692     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5693     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5694 }
5695
5696 static void cnd_test(IDirect3DDevice9 *device)
5697 {
5698     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5699     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5700     HRESULT hr;
5701     DWORD color;
5702     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5703      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5704      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5705      */
5706     DWORD shader_code_11[] =  {
5707         0xffff0101,                                                                 /* ps_1_1               */
5708         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5709         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5710         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5711         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5712         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5713         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5714         0x0000ffff                                                                  /* end                  */
5715     };
5716     DWORD shader_code_12[] =  {
5717         0xffff0102,                                                                 /* ps_1_2               */
5718         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5719         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5720         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5721         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5722         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5723         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5724         0x0000ffff                                                                  /* end                  */
5725     };
5726     DWORD shader_code_13[] =  {
5727         0xffff0103,                                                                 /* ps_1_3               */
5728         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5729         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5730         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5731         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5732         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5733         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5734         0x0000ffff                                                                  /* end                  */
5735     };
5736     DWORD shader_code_14[] =  {
5737         0xffff0104,                                                                 /* ps_1_3               */
5738         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5739         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5740         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5741         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5742         0x0000ffff                                                                  /* end                  */
5743     };
5744
5745     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5746      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5747      * set by the compiler, it was added manually after compilation. Note that the COISSUE
5748      * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5749      * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5750      * well enough.
5751      *
5752      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5753      * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5754      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5755      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5756      */
5757     DWORD shader_code_11_coissue[] =  {
5758         0xffff0101,                                                             /* ps_1_1                   */
5759         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5760         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5761         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5762         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5763         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5764         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5765         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5766         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5767         /* 0x40000000 = D3DSI_COISSUE */
5768         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5769         0x0000ffff                                                              /* end                      */
5770     };
5771     DWORD shader_code_12_coissue[] =  {
5772         0xffff0102,                                                             /* ps_1_2                   */
5773         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5774         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5775         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5776         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5777         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5778         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5779         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5780         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5781         /* 0x40000000 = D3DSI_COISSUE */
5782         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5783         0x0000ffff                                                              /* end                      */
5784     };
5785     DWORD shader_code_13_coissue[] =  {
5786         0xffff0103,                                                             /* ps_1_3                   */
5787         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5788         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5789         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5790         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5791         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5792         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5793         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5794         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5795         /* 0x40000000 = D3DSI_COISSUE */
5796         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5797         0x0000ffff                                                              /* end                      */
5798     };
5799     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5800      * compare against 0.5
5801      */
5802     DWORD shader_code_14_coissue[] =  {
5803         0xffff0104,                                                             /* ps_1_4                   */
5804         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5805         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5806         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5807         /* 0x40000000 = D3DSI_COISSUE */
5808         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5809         0x0000ffff                                                              /* end                      */
5810     };
5811     float quad1[] = {
5812         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5813          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5814         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5815          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5816     };
5817     float quad2[] = {
5818          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5819          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5820          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5821          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5822     };
5823     float quad3[] = {
5824          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5825          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5826          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5827          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5828     };
5829     float quad4[] = {
5830         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5831          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5832         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5833          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5834     };
5835     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5836     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5837     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5838     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5839
5840     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5841     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5842
5843     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5844     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5845     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5846     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5847     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5848     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5849     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5850     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5851     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5852     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5853     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5854     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5855     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5856     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5857     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5858     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5859
5860     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5861     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5862     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5863     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5864     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5865     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5866
5867     hr = IDirect3DDevice9_BeginScene(device);
5868     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5869     if(SUCCEEDED(hr))
5870     {
5871         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5872         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5873         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5874         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5875
5876         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5877         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5878         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5879         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5880
5881         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5882         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5883         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5884         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5885
5886         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5887         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5888         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5889         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5890
5891         hr = IDirect3DDevice9_EndScene(device);
5892         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5893     }
5894
5895     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5896     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5897
5898     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5899     color = getPixelColor(device, 158, 118);
5900     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5901     color = getPixelColor(device, 162, 118);
5902     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5903     color = getPixelColor(device, 158, 122);
5904     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5905     color = getPixelColor(device, 162, 122);
5906     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5907
5908     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5909     color = getPixelColor(device, 158, 358);
5910     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5911     color = getPixelColor(device, 162, 358);
5912     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5913         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5914     color = getPixelColor(device, 158, 362);
5915     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5916     color = getPixelColor(device, 162, 362);
5917     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5918         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5919
5920     /* 1.2 shader */
5921     color = getPixelColor(device, 478, 358);
5922     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5923     color = getPixelColor(device, 482, 358);
5924     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5925         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5926     color = getPixelColor(device, 478, 362);
5927     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5928     color = getPixelColor(device, 482, 362);
5929     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5930         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5931
5932     /* 1.3 shader */
5933     color = getPixelColor(device, 478, 118);
5934     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5935     color = getPixelColor(device, 482, 118);
5936     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5937         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5938     color = getPixelColor(device, 478, 122);
5939     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5940     color = getPixelColor(device, 482, 122);
5941     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5942         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5943
5944     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5945     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5946
5947     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5948     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5949     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5950     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5951     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5952     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5953
5954     hr = IDirect3DDevice9_BeginScene(device);
5955     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5956     if(SUCCEEDED(hr))
5957     {
5958         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5959         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5960         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5961         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5962
5963         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5964         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5965         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5966         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5967
5968         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5969         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5970         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5971         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5972
5973         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5974         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5975         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5976         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5977
5978         hr = IDirect3DDevice9_EndScene(device);
5979         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5980     }
5981
5982     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5983     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5984
5985     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5986      * that we swapped the values in c1 and c2 to make the other tests return some color
5987      */
5988     color = getPixelColor(device, 158, 118);
5989     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5990     color = getPixelColor(device, 162, 118);
5991     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5992     color = getPixelColor(device, 158, 122);
5993     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5994     color = getPixelColor(device, 162, 122);
5995     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5996
5997     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5998      * (The Win7 nvidia driver always selects c2)
5999      */
6000     color = getPixelColor(device, 158, 358);
6001     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
6002         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
6003     color = getPixelColor(device, 162, 358);
6004     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
6005         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
6006     color = getPixelColor(device, 158, 362);
6007     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
6008         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
6009     color = getPixelColor(device, 162, 362);
6010     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
6011         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
6012
6013     /* 1.2 shader */
6014     color = getPixelColor(device, 478, 358);
6015     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
6016         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
6017     color = getPixelColor(device, 482, 358);
6018     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
6019         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
6020     color = getPixelColor(device, 478, 362);
6021     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
6022         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
6023     color = getPixelColor(device, 482, 362);
6024     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
6025         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
6026
6027     /* 1.3 shader */
6028     color = getPixelColor(device, 478, 118);
6029     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
6030         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
6031     color = getPixelColor(device, 482, 118);
6032     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
6033         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
6034     color = getPixelColor(device, 478, 122);
6035     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
6036         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
6037     color = getPixelColor(device, 482, 122);
6038     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
6039         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
6040
6041     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6042     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6043
6044     IDirect3DPixelShader9_Release(shader_14_coissue);
6045     IDirect3DPixelShader9_Release(shader_13_coissue);
6046     IDirect3DPixelShader9_Release(shader_12_coissue);
6047     IDirect3DPixelShader9_Release(shader_11_coissue);
6048     IDirect3DPixelShader9_Release(shader_14);
6049     IDirect3DPixelShader9_Release(shader_13);
6050     IDirect3DPixelShader9_Release(shader_12);
6051     IDirect3DPixelShader9_Release(shader_11);
6052 }
6053
6054 static void nested_loop_test(IDirect3DDevice9 *device) {
6055     const DWORD shader_code[] = {
6056         0xffff0300,                                                             /* ps_3_0               */
6057         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
6058         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
6059         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
6060         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
6061         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
6062         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
6063         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
6064         0x0000001d,                                                             /* endloop              */
6065         0x0000001d,                                                             /* endloop              */
6066         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
6067         0x0000ffff                                                              /* end                  */
6068     };
6069     const DWORD vshader_code[] = {
6070         0xfffe0300,                                                             /* vs_3_0               */
6071         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
6072         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
6073         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
6074         0x0000ffff                                                              /* end                  */
6075     };
6076     IDirect3DPixelShader9 *shader;
6077     IDirect3DVertexShader9 *vshader;
6078     HRESULT hr;
6079     DWORD color;
6080     const float quad[] = {
6081         -1.0,   -1.0,   0.1,
6082          1.0,   -1.0,   0.1,
6083         -1.0,    1.0,   0.1,
6084          1.0,    1.0,   0.1
6085     };
6086
6087     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
6088     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
6089     hr = IDirect3DDevice9_SetPixelShader(device, shader);
6090     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
6091     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6092     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
6093     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6094     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
6095     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6096     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6097     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
6098     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6099
6100     hr = IDirect3DDevice9_BeginScene(device);
6101     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6102     if(SUCCEEDED(hr))
6103     {
6104         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6105         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6106         hr = IDirect3DDevice9_EndScene(device);
6107         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6108     }
6109
6110     color = getPixelColor(device, 360, 240);
6111     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
6112        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
6113
6114     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6115     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6116
6117     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6118     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
6119     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6120     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
6121     IDirect3DPixelShader9_Release(shader);
6122     IDirect3DVertexShader9_Release(vshader);
6123 }
6124
6125 struct varying_test_struct
6126 {
6127     const DWORD             *shader_code;
6128     IDirect3DPixelShader9   *shader;
6129     DWORD                   color, color_rhw;
6130     const char              *name;
6131     BOOL                    todo, todo_rhw;
6132 };
6133
6134 struct hugeVertex
6135 {
6136     float pos_x,        pos_y,      pos_z,      rhw;
6137     float weight_1,     weight_2,   weight_3,   weight_4;
6138     float index_1,      index_2,    index_3,    index_4;
6139     float normal_1,     normal_2,   normal_3,   normal_4;
6140     float fog_1,        fog_2,      fog_3,      fog_4;
6141     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
6142     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
6143     float binormal_1,   binormal_2, binormal_3, binormal_4;
6144     float depth_1,      depth_2,    depth_3,    depth_4;
6145     DWORD diffuse, specular;
6146 };
6147
6148 static void pretransformed_varying_test(IDirect3DDevice9 *device) {
6149     /* dcl_position: fails to compile */
6150     const DWORD blendweight_code[] = {
6151         0xffff0300,                             /* ps_3_0                   */
6152         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
6153         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6154         0x0000ffff                              /* end                      */
6155     };
6156     const DWORD blendindices_code[] = {
6157         0xffff0300,                             /* ps_3_0                   */
6158         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
6159         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6160         0x0000ffff                              /* end                      */
6161     };
6162     const DWORD normal_code[] = {
6163         0xffff0300,                             /* ps_3_0                   */
6164         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
6165         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6166         0x0000ffff                              /* end                      */
6167     };
6168     /* psize: fails? */
6169     const DWORD texcoord0_code[] = {
6170         0xffff0300,                             /* ps_3_0                   */
6171         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
6172         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6173         0x0000ffff                              /* end                      */
6174     };
6175     const DWORD tangent_code[] = {
6176         0xffff0300,                             /* ps_3_0                   */
6177         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
6178         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6179         0x0000ffff                              /* end                      */
6180     };
6181     const DWORD binormal_code[] = {
6182         0xffff0300,                             /* ps_3_0                   */
6183         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
6184         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6185         0x0000ffff                              /* end                      */
6186     };
6187     /* tessfactor: fails */
6188     /* positiont: fails */
6189     const DWORD color_code[] = {
6190         0xffff0300,                             /* ps_3_0                   */
6191         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
6192         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6193         0x0000ffff                              /* end                      */
6194     };
6195     const DWORD fog_code[] = {
6196         0xffff0300,                             /* ps_3_0                   */
6197         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
6198         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6199         0x0000ffff                              /* end                      */
6200     };
6201     const DWORD depth_code[] = {
6202         0xffff0300,                             /* ps_3_0                   */
6203         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
6204         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6205         0x0000ffff                              /* end                      */
6206     };
6207     const DWORD specular_code[] = {
6208         0xffff0300,                             /* ps_3_0                   */
6209         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
6210         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6211         0x0000ffff                              /* end                      */
6212     };
6213     /* sample: fails */
6214
6215     struct varying_test_struct tests[] = {
6216        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
6217        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
6218        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
6219        /* Why does dx not forward the texcoord? */
6220        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
6221        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
6222        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
6223        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
6224        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
6225        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
6226        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
6227     };
6228     /* Declare a monster vertex type :-) */
6229     static const D3DVERTEXELEMENT9 decl_elements[] = {
6230         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6231         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
6232         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
6233         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
6234         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
6235         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6236         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
6237         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
6238         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
6239         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6240         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
6241         D3DDECL_END()
6242     };
6243     struct hugeVertex data[4] = {
6244         {
6245             -1.0,   -1.0,   0.1,    1.0,
6246              0.1,    0.1,   0.1,    0.1,
6247              0.2,    0.2,   0.2,    0.2,
6248              0.3,    0.3,   0.3,    0.3,
6249              0.4,    0.4,   0.4,    0.4,
6250              0.50,   0.55,  0.55,   0.55,
6251              0.6,    0.6,   0.6,    0.7,
6252              0.7,    0.7,   0.7,    0.6,
6253              0.8,    0.8,   0.8,    0.8,
6254              0xe6e6e6e6, /* 0.9 * 256 */
6255              0x224488ff  /* Nothing special */
6256         },
6257         {
6258              1.0,   -1.0,   0.1,    1.0,
6259              0.1,    0.1,   0.1,    0.1,
6260              0.2,    0.2,   0.2,    0.2,
6261              0.3,    0.3,   0.3,    0.3,
6262              0.4,    0.4,   0.4,    0.4,
6263              0.50,   0.55,  0.55,   0.55,
6264              0.6,    0.6,   0.6,    0.7,
6265              0.7,    0.7,   0.7,    0.6,
6266              0.8,    0.8,   0.8,    0.8,
6267              0xe6e6e6e6, /* 0.9 * 256 */
6268              0x224488ff /* Nothing special */
6269         },
6270         {
6271             -1.0,    1.0,   0.1,    1.0,
6272              0.1,    0.1,   0.1,    0.1,
6273              0.2,    0.2,   0.2,    0.2,
6274              0.3,    0.3,   0.3,    0.3,
6275              0.4,    0.4,   0.4,    0.4,
6276              0.50,   0.55,  0.55,   0.55,
6277              0.6,    0.6,   0.6,    0.7,
6278              0.7,    0.7,   0.7,    0.6,
6279              0.8,    0.8,   0.8,    0.8,
6280              0xe6e6e6e6, /* 0.9 * 256 */
6281              0x224488ff /* Nothing special */
6282         },
6283         {
6284              1.0,    1.0,   0.1,    1.0,
6285              0.1,    0.1,   0.1,    0.1,
6286              0.2,    0.2,   0.2,    0.2,
6287              0.3,    0.3,   0.3,    0.3,
6288              0.4,    0.4,   0.4,    0.4,
6289              0.50,   0.55,  0.55,   0.55,
6290              0.6,    0.6,   0.6,    0.7,
6291              0.7,    0.7,   0.7,    0.6,
6292              0.8,    0.8,   0.8,    0.8,
6293              0xe6e6e6e6, /* 0.9 * 256 */
6294              0x224488ff /* Nothing special */
6295         },
6296     };
6297     struct hugeVertex data2[4];
6298     IDirect3DVertexDeclaration9 *decl;
6299     HRESULT hr;
6300     unsigned int i;
6301     DWORD color, r, g, b, r_e, g_e, b_e;
6302
6303     memcpy(data2, data, sizeof(data2));
6304     data2[0].pos_x = 0;     data2[0].pos_y = 0;
6305     data2[1].pos_x = 640;   data2[1].pos_y = 0;
6306     data2[2].pos_x = 0;     data2[2].pos_y = 480;
6307     data2[3].pos_x = 640;   data2[3].pos_y = 480;
6308
6309     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6310     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6311     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6312     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6313
6314     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6315     {
6316         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
6317         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
6318            tests[i].name, hr);
6319     }
6320
6321     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6322     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6323     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6324     {
6325         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6326         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6327
6328         hr = IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
6329         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6330
6331         hr = IDirect3DDevice9_BeginScene(device);
6332         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6333         if(SUCCEEDED(hr))
6334         {
6335             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
6336             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6337             hr = IDirect3DDevice9_EndScene(device);
6338             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6339         }
6340
6341         color = getPixelColor(device, 360, 240);
6342         r = color & 0x00ff0000 >> 16;
6343         g = color & 0x0000ff00 >>  8;
6344         b = color & 0x000000ff;
6345         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
6346         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
6347         b_e = tests[i].color_rhw & 0x000000ff;
6348
6349         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6350         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6351
6352         if(tests[i].todo_rhw) {
6353             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
6354              * pipeline
6355              */
6356             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6357                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
6358                          tests[i].name, color, tests[i].color_rhw);
6359         } else {
6360             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6361                "Test %s returned color 0x%08x, expected 0x%08x\n",
6362                tests[i].name, color, tests[i].color_rhw);
6363         }
6364     }
6365
6366     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6367     {
6368         IDirect3DPixelShader9_Release(tests[i].shader);
6369     }
6370
6371     IDirect3DVertexDeclaration9_Release(decl);
6372 }
6373
6374 static void test_compare_instructions(IDirect3DDevice9 *device)
6375 {
6376     DWORD shader_sge_vec_code[] = {
6377         0xfffe0101,                                         /* vs_1_1                   */
6378         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6379         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6380         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6381         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
6382         0x0000ffff                                          /* end                      */
6383     };
6384     DWORD shader_slt_vec_code[] = {
6385         0xfffe0101,                                         /* vs_1_1                   */
6386         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6387         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6388         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6389         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
6390         0x0000ffff                                          /* end                      */
6391     };
6392     DWORD shader_sge_scalar_code[] = {
6393         0xfffe0101,                                         /* vs_1_1                   */
6394         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6395         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6396         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6397         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
6398         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
6399         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
6400         0x0000ffff                                          /* end                      */
6401     };
6402     DWORD shader_slt_scalar_code[] = {
6403         0xfffe0101,                                         /* vs_1_1                   */
6404         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6405         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6406         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6407         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
6408         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
6409         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
6410         0x0000ffff                                          /* end                      */
6411     };
6412     IDirect3DVertexShader9 *shader_sge_vec;
6413     IDirect3DVertexShader9 *shader_slt_vec;
6414     IDirect3DVertexShader9 *shader_sge_scalar;
6415     IDirect3DVertexShader9 *shader_slt_scalar;
6416     HRESULT hr, color;
6417     float quad1[] =  {
6418         -1.0,   -1.0,   0.1,
6419          0.0,   -1.0,   0.1,
6420         -1.0,    0.0,   0.1,
6421          0.0,    0.0,   0.1
6422     };
6423     float quad2[] =  {
6424          0.0,   -1.0,   0.1,
6425          1.0,   -1.0,   0.1,
6426          0.0,    0.0,   0.1,
6427          1.0,    0.0,   0.1
6428     };
6429     float quad3[] =  {
6430         -1.0,    0.0,   0.1,
6431          0.0,    0.0,   0.1,
6432         -1.0,    1.0,   0.1,
6433          0.0,    1.0,   0.1
6434     };
6435     float quad4[] =  {
6436          0.0,    0.0,   0.1,
6437          1.0,    0.0,   0.1,
6438          0.0,    1.0,   0.1,
6439          1.0,    1.0,   0.1
6440     };
6441     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6442     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6443
6444     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6445     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6446
6447     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6448     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6449     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6450     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6451     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6452     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6453     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6454     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6455     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6456     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6457     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6458     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6459     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6460     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6461
6462     hr = IDirect3DDevice9_BeginScene(device);
6463     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6464     if(SUCCEEDED(hr))
6465     {
6466         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6467         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6468         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6469         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6470
6471         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6472         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6473         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6474         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6475
6476         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6477         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6478         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6479         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6480
6481         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6482         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6483
6484         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6485         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6486         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6487         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6488
6489         hr = IDirect3DDevice9_EndScene(device);
6490         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6491     }
6492
6493     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6494     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6495
6496     color = getPixelColor(device, 160, 360);
6497     ok(color == 0x00ff00ff, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00ff00ff\n", color);
6498     color = getPixelColor(device, 480, 360);
6499     ok(color == 0x0000ff00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000ff00\n", color);
6500     color = getPixelColor(device, 160, 120);
6501     ok(color == 0x00ffffff, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00ffffff\n", color);
6502     color = getPixelColor(device, 480, 160);
6503     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6504
6505     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6506     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6507
6508     IDirect3DVertexShader9_Release(shader_sge_vec);
6509     IDirect3DVertexShader9_Release(shader_slt_vec);
6510     IDirect3DVertexShader9_Release(shader_sge_scalar);
6511     IDirect3DVertexShader9_Release(shader_slt_scalar);
6512 }
6513
6514 static void test_vshader_input(IDirect3DDevice9 *device)
6515 {
6516     static const DWORD swapped_shader_code_3[] =
6517     {
6518         0xfffe0300,                                         /* vs_3_0               */
6519         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6520         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6521         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6522         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6523         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6524         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6525         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6526         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6527         0x0000ffff                                          /* end                  */
6528     };
6529     static const DWORD swapped_shader_code_1[] =
6530     {
6531         0xfffe0101,                                         /* vs_1_1               */
6532         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6533         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6534         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6535         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6536         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6537         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6538         0x0000ffff                                          /* end                  */
6539     };
6540     static const DWORD swapped_shader_code_2[] =
6541     {
6542         0xfffe0200,                                         /* vs_2_0               */
6543         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6544         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6545         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6546         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6547         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6548         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6549         0x0000ffff                                          /* end                  */
6550     };
6551     static const DWORD texcoord_color_shader_code_3[] =
6552     {
6553         0xfffe0300,                                         /* vs_3_0               */
6554         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6555         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6556         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6557         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6558         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6559         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6560         0x0000ffff                                          /* end                  */
6561     };
6562     static const DWORD texcoord_color_shader_code_2[] =
6563     {
6564         0xfffe0200,                                         /* vs_2_0               */
6565         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6566         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6567         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6568         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6569         0x0000ffff                                          /* end                  */
6570     };
6571     static const DWORD texcoord_color_shader_code_1[] =
6572     {
6573         0xfffe0101,                                         /* vs_1_1               */
6574         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6575         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6576         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6577         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6578         0x0000ffff                                          /* end                  */
6579     };
6580     static const DWORD color_color_shader_code_3[] =
6581     {
6582         0xfffe0300,                                         /* vs_3_0               */
6583         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6584         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6585         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6586         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6587         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6588         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6589         0x0000ffff                                          /* end                  */
6590     };
6591     static const DWORD color_color_shader_code_2[] =
6592     {
6593         0xfffe0200,                                         /* vs_2_0               */
6594         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6595         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6596         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6597         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6598         0x0000ffff                                          /* end                  */
6599     };
6600     static const DWORD color_color_shader_code_1[] =
6601     {
6602         0xfffe0101,                                         /* vs_1_1               */
6603         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6604         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6605         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6606         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6607         0x0000ffff                                          /* end                  */
6608     };
6609     static const DWORD ps3_code[] =
6610     {
6611         0xffff0300,                                         /* ps_3_0               */
6612         0x0200001f, 0x8000000a, 0x900f0000,                 /* dcl_color0 v0        */
6613         0x02000001, 0x800f0800, 0x90e40000,                 /* mov oC0, v0          */
6614         0x0000ffff                                          /* end                  */
6615     };
6616     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6617     IDirect3DPixelShader9 *ps;
6618     HRESULT hr;
6619     DWORD color;
6620     float quad1[] =  {
6621         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6622          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6623         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6624          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6625     };
6626     float quad2[] =  {
6627          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6628          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6629          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6630          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6631     };
6632     float quad3[] =  {
6633         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6634          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6635         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6636          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6637     };
6638     float quad4[] =  {
6639          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6640          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6641          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6642          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6643     };
6644     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6645         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6646         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6647         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6648         D3DDECL_END()
6649     };
6650     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6651         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6652         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6653         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6654         D3DDECL_END()
6655     };
6656     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6657         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6658         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6659         D3DDECL_END()
6660     };
6661     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6662         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6663         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6664         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6665         D3DDECL_END()
6666     };
6667     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6668         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6669         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6670         D3DDECL_END()
6671     };
6672     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6673         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6674         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6675         D3DDECL_END()
6676     };
6677     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6678         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6679         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6680         D3DDECL_END()
6681     };
6682     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6683         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6684         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6685         D3DDECL_END()
6686     };
6687     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6688     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6689     unsigned int i;
6690     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6691     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6692
6693     struct vertex quad1_color[] =  {
6694        {-1.0,   -1.0,   0.1,    0x00ff8040},
6695        { 0.0,   -1.0,   0.1,    0x00ff8040},
6696        {-1.0,    0.0,   0.1,    0x00ff8040},
6697        { 0.0,    0.0,   0.1,    0x00ff8040}
6698     };
6699     struct vertex quad2_color[] =  {
6700        { 0.0,   -1.0,   0.1,    0x00ff8040},
6701        { 1.0,   -1.0,   0.1,    0x00ff8040},
6702        { 0.0,    0.0,   0.1,    0x00ff8040},
6703        { 1.0,    0.0,   0.1,    0x00ff8040}
6704     };
6705     struct vertex quad3_color[] =  {
6706        {-1.0,    0.0,   0.1,    0x00ff8040},
6707        { 0.0,    0.0,   0.1,    0x00ff8040},
6708        {-1.0,    1.0,   0.1,    0x00ff8040},
6709        { 0.0,    1.0,   0.1,    0x00ff8040}
6710     };
6711     float quad4_color[] =  {
6712          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6713          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6714          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6715          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6716     };
6717
6718     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6719     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6720     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6721     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6722     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6723     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6724     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6725     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6726
6727     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6728     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6729     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6730     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6731     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6732     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6733     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6734     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6735
6736     hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
6737     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6738
6739     for(i = 1; i <= 3; i++) {
6740         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6741         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6742         if(i == 3) {
6743             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6744             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6745             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6746             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6747         } else if(i == 2){
6748             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6749             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6750         } else if(i == 1) {
6751             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6752             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6753         }
6754
6755         hr = IDirect3DDevice9_BeginScene(device);
6756         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6757         if(SUCCEEDED(hr))
6758         {
6759             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6760             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6761
6762             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6763             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6764             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6765             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6766
6767             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6768             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6769             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6770             if(i == 3 || i == 2) {
6771                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6772             } else if(i == 1) {
6773                 /* Succeeds or fails, depending on SW or HW vertex processing */
6774                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6775             }
6776
6777             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6778             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6779             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6780             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6781
6782             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6783             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6784             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6785             if(i == 3 || i == 2) {
6786                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6787             } else if(i == 1) {
6788                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6789             }
6790
6791             hr = IDirect3DDevice9_EndScene(device);
6792             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6793         }
6794
6795         if(i == 3 || i == 2) {
6796             color = getPixelColor(device, 160, 360);
6797             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6798                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
6799
6800             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6801             color = getPixelColor(device, 480, 360);
6802             ok(color == 0x00ffff00 || color ==0x00ff0000,
6803                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00ffff00\n", color);
6804             color = getPixelColor(device, 160, 120);
6805             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6806             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6807                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
6808
6809             color = getPixelColor(device, 480, 160);
6810             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6811         } else if(i == 1) {
6812             color = getPixelColor(device, 160, 360);
6813             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6814                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
6815             color = getPixelColor(device, 480, 360);
6816             /* Accept the clear color as well in this case, since SW VP returns an error */
6817             ok(color == 0x00ffff00 || color == 0x00ff0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00ffff00\n", color);
6818             color = getPixelColor(device, 160, 120);
6819             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6820                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
6821             color = getPixelColor(device, 480, 160);
6822             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6823         }
6824
6825         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6826         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6827
6828         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6829         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6830
6831         /* Now find out if the whole streams are re-read, or just the last active value for the
6832          * vertices is used.
6833          */
6834         hr = IDirect3DDevice9_BeginScene(device);
6835         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6836         if(SUCCEEDED(hr))
6837         {
6838             float quad1_modified[] =  {
6839                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6840                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6841                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6842                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6843             };
6844             float quad2_modified[] =  {
6845                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6846                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6847                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6848                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6849             };
6850
6851             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6852             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6853
6854             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6855             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6856             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6857             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6858
6859             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6860             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6861             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6862             if(i == 3 || i == 2) {
6863                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6864             } else if(i == 1) {
6865                 /* Succeeds or fails, depending on SW or HW vertex processing */
6866                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6867             }
6868
6869             hr = IDirect3DDevice9_EndScene(device);
6870             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6871         }
6872
6873         color = getPixelColor(device, 480, 350);
6874         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6875          * as well.
6876          *
6877          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6878          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6879          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6880          * refrast's result.
6881          *
6882          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6883          */
6884         ok(color == 0x000000ff || color == 0x00808080 || color == 0x00000000,
6885            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000ff, 0x00808080 or 0x00000000\n", color);
6886
6887         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6888         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6889
6890         IDirect3DDevice9_SetVertexShader(device, NULL);
6891         IDirect3DDevice9_SetPixelShader(device, NULL);
6892         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6893
6894         IDirect3DVertexShader9_Release(swapped_shader);
6895     }
6896
6897     for(i = 1; i <= 3; i++) {
6898         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6899         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6900         if(i == 3) {
6901             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6902             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6903             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6904             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6905             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6906             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6907         } else if(i == 2){
6908             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6909             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6910             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6911             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6912         } else if(i == 1) {
6913             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6914             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6915             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6916             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6917         }
6918
6919         hr = IDirect3DDevice9_BeginScene(device);
6920         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6921         if(SUCCEEDED(hr))
6922         {
6923             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6924             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6925             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6926             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6927             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6928             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6929
6930             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6931             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6932
6933             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6934             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6935             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6936             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6937             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6938             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6939
6940             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6941             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6942             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6943             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6944             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6945             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6946
6947             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6948             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6949             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6950             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6951
6952             hr = IDirect3DDevice9_EndScene(device);
6953             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6954         }
6955         IDirect3DDevice9_SetVertexShader(device, NULL);
6956         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6957         IDirect3DDevice9_SetPixelShader(device, NULL);
6958
6959         color = getPixelColor(device, 160, 360);
6960         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6961            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6962         color = getPixelColor(device, 480, 360);
6963         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6964            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6965         color = getPixelColor(device, 160, 120);
6966         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6967            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6968         color = getPixelColor(device, 480, 160);
6969         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6970            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
6971
6972         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6973         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6974
6975         IDirect3DVertexShader9_Release(texcoord_color_shader);
6976         IDirect3DVertexShader9_Release(color_color_shader);
6977     }
6978
6979     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6980     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6981     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6982     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6983
6984     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6985     IDirect3DVertexDeclaration9_Release(decl_color_color);
6986     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6987     IDirect3DVertexDeclaration9_Release(decl_color_float);
6988
6989     IDirect3DPixelShader9_Release(ps);
6990 }
6991
6992 static void srgbtexture_test(IDirect3DDevice9 *device)
6993 {
6994     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6995      * texture stage state to render a quad using that texture.  The resulting
6996      * color components should be 0x36 (~ 0.21), per this formula:
6997      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6998      * This is true where srgb_color > 0.04045. */
6999     struct IDirect3DTexture9 *texture = NULL;
7000     struct IDirect3DSurface9 *surface = NULL;
7001     IDirect3D9 *d3d = NULL;
7002     HRESULT hr;
7003     D3DLOCKED_RECT lr;
7004     DWORD color;
7005     float quad[] = {
7006         -1.0,       1.0,       0.0,     0.0,    0.0,
7007          1.0,       1.0,       0.0,     1.0,    0.0,
7008         -1.0,      -1.0,       0.0,     0.0,    1.0,
7009          1.0,      -1.0,       0.0,     1.0,    1.0,
7010     };
7011
7012
7013     memset(&lr, 0, sizeof(lr));
7014     IDirect3DDevice9_GetDirect3D(device, &d3d);
7015     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7016                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
7017                                     D3DFMT_A8R8G8B8) != D3D_OK) {
7018         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
7019         goto out;
7020     }
7021
7022     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
7023                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
7024                                         &texture, NULL);
7025     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
7026     if(!texture) {
7027         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
7028         goto out;
7029     }
7030     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7031     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
7032
7033     fill_surface(surface, 0xff7f7f7f);
7034     IDirect3DSurface9_Release(surface);
7035
7036     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7037     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7038     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7039     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
7040
7041     hr = IDirect3DDevice9_BeginScene(device);
7042     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7043     if(SUCCEEDED(hr))
7044     {
7045         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
7046         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
7047
7048         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7049         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7050
7051
7052         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
7053         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
7054
7055         hr = IDirect3DDevice9_EndScene(device);
7056         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7057     }
7058
7059     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7060     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
7061     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
7062     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
7063
7064     color = getPixelColor(device, 320, 240);
7065     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
7066
7067     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7068     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7069
7070 out:
7071     if(texture) IDirect3DTexture9_Release(texture);
7072     IDirect3D9_Release(d3d);
7073 }
7074
7075 static void shademode_test(IDirect3DDevice9 *device)
7076 {
7077     /* Render a quad and try all of the different fixed function shading models. */
7078     struct IDirect3DVertexBuffer9 *vb_strip = NULL;
7079     struct IDirect3DVertexBuffer9 *vb_list = NULL;
7080     HRESULT hr;
7081     DWORD color0, color1;
7082     DWORD color0_gouraud = 0, color1_gouraud = 0;
7083     DWORD shademode = D3DSHADE_FLAT;
7084     DWORD primtype = D3DPT_TRIANGLESTRIP;
7085     LPVOID data = NULL;
7086     UINT i, j;
7087     struct vertex quad_strip[] =
7088     {
7089         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
7090         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
7091         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
7092         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
7093     };
7094     struct vertex quad_list[] =
7095     {
7096         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
7097         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
7098         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
7099
7100         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
7101         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
7102         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
7103     };
7104
7105     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
7106                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
7107     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7108     if (FAILED(hr)) goto bail;
7109
7110     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
7111                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
7112     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7113     if (FAILED(hr)) goto bail;
7114
7115     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7116     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7117
7118     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7119     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7120
7121     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
7122     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7123     memcpy(data, quad_strip, sizeof(quad_strip));
7124     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
7125     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7126
7127     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
7128     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7129     memcpy(data, quad_list, sizeof(quad_list));
7130     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
7131     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7132
7133     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
7134      * the color fixups we have to do for FLAT shading will be dependent on that. */
7135     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
7136     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7137
7138     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
7139     for (j=0; j<2; j++) {
7140
7141         /* Inner loop just changes the D3DRS_SHADEMODE */
7142         for (i=0; i<3; i++) {
7143             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7144             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7145
7146             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
7147             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7148
7149             hr = IDirect3DDevice9_BeginScene(device);
7150             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7151             if(SUCCEEDED(hr))
7152             {
7153                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
7154                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
7155
7156                 hr = IDirect3DDevice9_EndScene(device);
7157                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7158             }
7159
7160             /* Sample two spots from the output */
7161             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
7162             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
7163             switch(shademode) {
7164                 case D3DSHADE_FLAT:
7165                     /* Should take the color of the first vertex of each triangle */
7166                     if (0)
7167                     {
7168                         /* This test depends on EXT_provoking_vertex being
7169                          * available. This extension is currently (20090810)
7170                          * not common enough to let the test fail if it isn't
7171                          * present. */
7172                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
7173                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
7174                     }
7175                     shademode = D3DSHADE_GOURAUD;
7176                     break;
7177                 case D3DSHADE_GOURAUD:
7178                     /* Should be an interpolated blend */
7179
7180                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7181                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
7182                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7183                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
7184
7185                     color0_gouraud = color0;
7186                     color1_gouraud = color1;
7187
7188                     shademode = D3DSHADE_PHONG;
7189                     break;
7190                 case D3DSHADE_PHONG:
7191                     /* Should be the same as GOURAUD, since no hardware implements this */
7192                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7193                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
7194                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7195                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7196
7197                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7198                             color0_gouraud, color0);
7199                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7200                             color1_gouraud, color1);
7201                     break;
7202             }
7203         }
7204
7205         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7206         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7207
7208         /* Now, do it all over again with a TRIANGLELIST */
7209         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7210         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7211         primtype = D3DPT_TRIANGLELIST;
7212         shademode = D3DSHADE_FLAT;
7213     }
7214
7215 bail:
7216     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7217     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7218     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7219     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7220
7221     if (vb_strip)
7222         IDirect3DVertexBuffer9_Release(vb_strip);
7223     if (vb_list)
7224         IDirect3DVertexBuffer9_Release(vb_list);
7225 }
7226
7227 static void alpha_test(IDirect3DDevice9 *device)
7228 {
7229     HRESULT hr;
7230     IDirect3DTexture9 *offscreenTexture;
7231     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7232     DWORD color;
7233
7234     struct vertex quad1[] =
7235     {
7236         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
7237         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
7238         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
7239         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
7240     };
7241     struct vertex quad2[] =
7242     {
7243         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
7244         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
7245         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
7246         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
7247     };
7248     static const float composite_quad[][5] = {
7249         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7250         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
7251         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7252         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
7253     };
7254
7255     /* Clear the render target with alpha = 0.5 */
7256     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7257     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7258
7259     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7260     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7261
7262     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7263     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7264     if(!backbuffer) {
7265         goto out;
7266     }
7267
7268     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7269     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7270     if(!offscreen) {
7271         goto out;
7272     }
7273
7274     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7275     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7276
7277     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7278     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7279     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7280     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7281     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7282     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7283     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7284     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7285     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7286     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7287
7288     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7289     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7290     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7291
7292         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7293         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7294         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7295         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7296         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7297         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7298         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7299
7300         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7301         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7302         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7303         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7304         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7305         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7306
7307         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7308          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7309          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7310         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7311         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7312         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7313         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7314
7315         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7316         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7317         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7318         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7319         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7320         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7321
7322         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7323         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7324         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7325         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7326         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7327         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7328
7329         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7330         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7331
7332         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7333          * Disable alpha blending for the final composition
7334          */
7335         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7336         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7337         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7338         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7339
7340         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7341         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7342         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7343         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7344         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7345         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7346
7347         hr = IDirect3DDevice9_EndScene(device);
7348         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7349     }
7350
7351     color = getPixelColor(device, 160, 360);
7352     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7353        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7354
7355     color = getPixelColor(device, 160, 120);
7356     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7357        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7358
7359     color = getPixelColor(device, 480, 360);
7360     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7361        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7362
7363     color = getPixelColor(device, 480, 120);
7364     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7365        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7366
7367     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7368
7369     out:
7370     /* restore things */
7371     if(backbuffer) {
7372         IDirect3DSurface9_Release(backbuffer);
7373     }
7374     if(offscreenTexture) {
7375         IDirect3DTexture9_Release(offscreenTexture);
7376     }
7377     if(offscreen) {
7378         IDirect3DSurface9_Release(offscreen);
7379     }
7380 }
7381
7382 struct vertex_shortcolor {
7383     float x, y, z;
7384     unsigned short r, g, b, a;
7385 };
7386 struct vertex_floatcolor {
7387     float x, y, z;
7388     float r, g, b, a;
7389 };
7390
7391 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7392 {
7393     HRESULT hr;
7394     BOOL s_ok, ub_ok, f_ok;
7395     DWORD color, size, i;
7396     void *data;
7397     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7398         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7399         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7400         D3DDECL_END()
7401     };
7402     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7403         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7404         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7405         D3DDECL_END()
7406     };
7407     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7408         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7409         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7410         D3DDECL_END()
7411     };
7412     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7413         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7414         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7415         D3DDECL_END()
7416     };
7417     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7418         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7419         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7420         D3DDECL_END()
7421     };
7422     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7423         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7424         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7425         D3DDECL_END()
7426     };
7427     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7428         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
7429         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7430         D3DDECL_END()
7431     };
7432     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7433     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7434     IDirect3DVertexBuffer9 *vb, *vb2;
7435     struct vertex quad1[] =                             /* D3DCOLOR */
7436     {
7437         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
7438         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7439         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
7440         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7441     };
7442     struct vertex quad2[] =                             /* UBYTE4N */
7443     {
7444         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7445         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
7446         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7447         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
7448     };
7449     struct vertex_shortcolor quad3[] =                  /* short */
7450     {
7451         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7452         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7453         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7454         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7455     };
7456     struct vertex_floatcolor quad4[] =
7457     {
7458         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7459         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7460         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7461         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7462     };
7463     DWORD colors[] = {
7464         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7465         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7466         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7467         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7468         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7469         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7470         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7471         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7472         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7473         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7474         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7475         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7476         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7477         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7478         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7479         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7480     };
7481     float quads[] = {
7482         -1.0,   -1.0,     0.1,
7483         -1.0,    0.0,     0.1,
7484          0.0,   -1.0,     0.1,
7485          0.0,    0.0,     0.1,
7486
7487          0.0,   -1.0,     0.1,
7488          0.0,    0.0,     0.1,
7489          1.0,   -1.0,     0.1,
7490          1.0,    0.0,     0.1,
7491
7492          0.0,    0.0,     0.1,
7493          0.0,    1.0,     0.1,
7494          1.0,    0.0,     0.1,
7495          1.0,    1.0,     0.1,
7496
7497         -1.0,    0.0,     0.1,
7498         -1.0,    1.0,     0.1,
7499          0.0,    0.0,     0.1,
7500          0.0,    1.0,     0.1
7501     };
7502     struct tvertex quad_transformed[] = {
7503        {  90,    110,     0.1,      2.0,        0x00ffff00},
7504        { 570,    110,     0.1,      2.0,        0x00ffff00},
7505        {  90,    300,     0.1,      2.0,        0x00ffff00},
7506        { 570,    300,     0.1,      2.0,        0x00ffff00}
7507     };
7508     D3DCAPS9 caps;
7509
7510     memset(&caps, 0, sizeof(caps));
7511     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7512     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7513
7514     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7515     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7516
7517     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7518     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7519     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7520     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7521     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7522     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7523     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7524         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7525         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7526         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7527         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7528     } else {
7529         trace("D3DDTCAPS_UBYTE4N not supported\n");
7530         dcl_ubyte_2 = NULL;
7531         dcl_ubyte = NULL;
7532     }
7533     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7534     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7535     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7536     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7537
7538     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7539     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7540                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7541     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7542
7543     hr = IDirect3DDevice9_BeginScene(device);
7544     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7545     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7546     if(SUCCEEDED(hr)) {
7547         if(dcl_color) {
7548             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7549             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7550             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7551             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7552         }
7553
7554         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7555          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7556          * using software vertex processing. Doh!
7557          */
7558         if(dcl_ubyte) {
7559             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7560             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7561             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7562             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7563             ub_ok = SUCCEEDED(hr);
7564         }
7565
7566         if(dcl_short) {
7567             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7568             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7569             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7570             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7571             s_ok = SUCCEEDED(hr);
7572         }
7573
7574         if(dcl_float) {
7575             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7576             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7577             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7578             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7579             f_ok = SUCCEEDED(hr);
7580         }
7581
7582         hr = IDirect3DDevice9_EndScene(device);
7583         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7584     }
7585
7586     if(dcl_short) {
7587         color = getPixelColor(device, 480, 360);
7588         ok(color == 0x000000ff || !s_ok,
7589            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7590     }
7591     if(dcl_ubyte) {
7592         color = getPixelColor(device, 160, 120);
7593         ok(color == 0x0000ffff || !ub_ok,
7594            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7595     }
7596     if(dcl_color) {
7597         color = getPixelColor(device, 160, 360);
7598         ok(color == 0x00ffff00,
7599            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7600     }
7601     if(dcl_float) {
7602         color = getPixelColor(device, 480, 120);
7603         ok(color == 0x00ff0000 || !f_ok,
7604            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7605     }
7606     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7607
7608     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7609      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7610      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7611      * whether the immediate mode code works
7612      */
7613     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7614     hr = IDirect3DDevice9_BeginScene(device);
7615     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7616     if(SUCCEEDED(hr)) {
7617         if(dcl_color) {
7618             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7619             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7620             memcpy(data, quad1, sizeof(quad1));
7621             hr = IDirect3DVertexBuffer9_Unlock(vb);
7622             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7623             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7624             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7625             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7626             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7627             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7628             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7629         }
7630
7631         if(dcl_ubyte) {
7632             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7633             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7634             memcpy(data, quad2, sizeof(quad2));
7635             hr = IDirect3DVertexBuffer9_Unlock(vb);
7636             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7637             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7638             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7639             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7640             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7641             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7642             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7643                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7644             ub_ok = SUCCEEDED(hr);
7645         }
7646
7647         if(dcl_short) {
7648             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7649             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7650             memcpy(data, quad3, sizeof(quad3));
7651             hr = IDirect3DVertexBuffer9_Unlock(vb);
7652             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7653             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7654             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7655             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7656             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7657             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7658             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7659                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7660             s_ok = SUCCEEDED(hr);
7661         }
7662
7663         if(dcl_float) {
7664             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7665             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7666             memcpy(data, quad4, sizeof(quad4));
7667             hr = IDirect3DVertexBuffer9_Unlock(vb);
7668             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7669             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7670             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7671             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7672             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7673             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7674             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7675                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7676             f_ok = SUCCEEDED(hr);
7677         }
7678
7679         hr = IDirect3DDevice9_EndScene(device);
7680         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7681     }
7682
7683     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7684     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7685     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7686     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7687
7688     if(dcl_short) {
7689         color = getPixelColor(device, 480, 360);
7690         ok(color == 0x000000ff || !s_ok,
7691            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7692     }
7693     if(dcl_ubyte) {
7694         color = getPixelColor(device, 160, 120);
7695         ok(color == 0x0000ffff || !ub_ok,
7696            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7697     }
7698     if(dcl_color) {
7699         color = getPixelColor(device, 160, 360);
7700         ok(color == 0x00ffff00,
7701            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7702     }
7703     if(dcl_float) {
7704         color = getPixelColor(device, 480, 120);
7705         ok(color == 0x00ff0000 || !f_ok,
7706            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7707     }
7708     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7709
7710     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7711     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7712
7713     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7714     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7715     memcpy(data, quad_transformed, sizeof(quad_transformed));
7716     hr = IDirect3DVertexBuffer9_Unlock(vb);
7717     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7718
7719     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7720     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7721
7722     hr = IDirect3DDevice9_BeginScene(device);
7723     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7724     if(SUCCEEDED(hr)) {
7725         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7726         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7727         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7728         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7729
7730         hr = IDirect3DDevice9_EndScene(device);
7731         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7732     }
7733
7734     color = getPixelColor(device, 88, 108);
7735     ok(color == 0x000000ff,
7736        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7737     color = getPixelColor(device, 92, 108);
7738     ok(color == 0x000000ff,
7739        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7740     color = getPixelColor(device, 88, 112);
7741     ok(color == 0x000000ff,
7742        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7743     color = getPixelColor(device, 92, 112);
7744     ok(color == 0x00ffff00,
7745        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7746
7747     color = getPixelColor(device, 568, 108);
7748     ok(color == 0x000000ff,
7749        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7750     color = getPixelColor(device, 572, 108);
7751     ok(color == 0x000000ff,
7752        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7753     color = getPixelColor(device, 568, 112);
7754     ok(color == 0x00ffff00,
7755        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7756     color = getPixelColor(device, 572, 112);
7757     ok(color == 0x000000ff,
7758        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7759
7760     color = getPixelColor(device, 88, 298);
7761     ok(color == 0x000000ff,
7762        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7763     color = getPixelColor(device, 92, 298);
7764     ok(color == 0x00ffff00,
7765        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7766     color = getPixelColor(device, 88, 302);
7767     ok(color == 0x000000ff,
7768        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7769     color = getPixelColor(device, 92, 302);
7770     ok(color == 0x000000ff,
7771        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7772
7773     color = getPixelColor(device, 568, 298);
7774     ok(color == 0x00ffff00,
7775        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7776     color = getPixelColor(device, 572, 298);
7777     ok(color == 0x000000ff,
7778        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7779     color = getPixelColor(device, 568, 302);
7780     ok(color == 0x000000ff,
7781        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7782     color = getPixelColor(device, 572, 302);
7783     ok(color == 0x000000ff,
7784        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7785
7786     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7787
7788     /* This test is pointless without those two declarations: */
7789     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7790         skip("color-ubyte switching test declarations aren't supported\n");
7791         goto out;
7792     }
7793
7794     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7795     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7796     memcpy(data, quads, sizeof(quads));
7797     hr = IDirect3DVertexBuffer9_Unlock(vb);
7798     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7799     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7800                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7801     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7802     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7803     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7804     memcpy(data, colors, sizeof(colors));
7805     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7806     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7807
7808     for(i = 0; i < 2; i++) {
7809         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7810         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7811
7812         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7813         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7814         if(i == 0) {
7815             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7816         } else {
7817             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7818         }
7819         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7820
7821         hr = IDirect3DDevice9_BeginScene(device);
7822         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7823         ub_ok = FALSE;
7824         if(SUCCEEDED(hr)) {
7825             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7826             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7827             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7828             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7829                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7830             ub_ok = SUCCEEDED(hr);
7831
7832             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7833             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7834             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7835             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7836
7837             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7838             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7839             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7840             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7841                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7842             ub_ok = (SUCCEEDED(hr) && ub_ok);
7843
7844             hr = IDirect3DDevice9_EndScene(device);
7845             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7846         }
7847
7848         if(i == 0) {
7849             color = getPixelColor(device, 480, 360);
7850             ok(color == 0x00ff0000,
7851                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7852             color = getPixelColor(device, 160, 120);
7853             ok(color == 0x00ffffff,
7854                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7855             color = getPixelColor(device, 160, 360);
7856             ok(color == 0x000000ff || !ub_ok,
7857                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7858             color = getPixelColor(device, 480, 120);
7859             ok(color == 0x000000ff || !ub_ok,
7860                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7861         } else {
7862             color = getPixelColor(device, 480, 360);
7863             ok(color == 0x000000ff,
7864                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7865             color = getPixelColor(device, 160, 120);
7866             ok(color == 0x00ffffff,
7867                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7868             color = getPixelColor(device, 160, 360);
7869             ok(color == 0x00ff0000 || !ub_ok,
7870                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7871             color = getPixelColor(device, 480, 120);
7872             ok(color == 0x00ff0000 || !ub_ok,
7873                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7874         }
7875         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7876     }
7877
7878     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7879     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7880     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7881     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7882     IDirect3DVertexBuffer9_Release(vb2);
7883
7884     out:
7885     IDirect3DVertexBuffer9_Release(vb);
7886     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7887     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7888     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7889     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7890     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7891     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7892     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7893 }
7894
7895 struct vertex_float16color {
7896     float x, y, z;
7897     DWORD c1, c2;
7898 };
7899
7900 static void test_vshader_float16(IDirect3DDevice9 *device)
7901 {
7902     HRESULT hr;
7903     DWORD color;
7904     void *data;
7905     static const D3DVERTEXELEMENT9 decl_elements[] = {
7906         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7907         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7908         D3DDECL_END()
7909     };
7910     IDirect3DVertexDeclaration9 *vdecl = NULL;
7911     IDirect3DVertexBuffer9 *buffer = NULL;
7912     IDirect3DVertexShader9 *shader;
7913     DWORD shader_code[] = {
7914         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7915         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7916         0x90e40001, 0x0000ffff
7917     };
7918     struct vertex_float16color quad[] = {
7919         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7920         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7921         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7922         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7923
7924         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7925         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7926         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7927         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7928
7929         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7930         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7931         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7932         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7933
7934         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7935         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7936         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7937         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7938     };
7939
7940     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7941     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7942
7943     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7944     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7945     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7946     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7947     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7948     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7949
7950     hr = IDirect3DDevice9_BeginScene(device);
7951     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7952     if(SUCCEEDED(hr)) {
7953         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7954         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7955         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7956         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7957         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7958         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7959         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7960         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7961         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7962         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7963
7964         hr = IDirect3DDevice9_EndScene(device);
7965         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7966     }
7967     color = getPixelColor(device, 480, 360);
7968     ok(color == 0x00ff0000,
7969        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7970     color = getPixelColor(device, 160, 120);
7971     ok(color == 0x00000000,
7972        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7973     color = getPixelColor(device, 160, 360);
7974     ok(color == 0x0000ff00,
7975        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7976     color = getPixelColor(device, 480, 120);
7977     ok(color == 0x000000ff,
7978        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7979     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7980
7981     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7982     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7983
7984     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7985                                              D3DPOOL_MANAGED, &buffer, NULL);
7986     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7987     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7988     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7989     memcpy(data, quad, sizeof(quad));
7990     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7991     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7992     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7993     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7994
7995     hr = IDirect3DDevice9_BeginScene(device);
7996     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7997     if(SUCCEEDED(hr)) {
7998             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7999             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8000             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
8001             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8002             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
8003             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8004             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
8005             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8006
8007             hr = IDirect3DDevice9_EndScene(device);
8008             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8009     }
8010
8011     color = getPixelColor(device, 480, 360);
8012     ok(color == 0x00ff0000,
8013        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
8014     color = getPixelColor(device, 160, 120);
8015     ok(color == 0x00000000,
8016        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
8017     color = getPixelColor(device, 160, 360);
8018     ok(color == 0x0000ff00,
8019        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
8020     color = getPixelColor(device, 480, 120);
8021     ok(color == 0x000000ff,
8022        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
8023     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8024
8025     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
8026     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
8027     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8028     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8029     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8030     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8031
8032     IDirect3DVertexDeclaration9_Release(vdecl);
8033     IDirect3DVertexShader9_Release(shader);
8034     IDirect3DVertexBuffer9_Release(buffer);
8035 }
8036
8037 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
8038 {
8039     D3DCAPS9 caps;
8040     IDirect3DTexture9 *texture;
8041     HRESULT hr;
8042     D3DLOCKED_RECT rect;
8043     unsigned int x, y;
8044     DWORD *dst, color;
8045     const float quad[] = {
8046         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
8047          1.0,   -1.0,   0.1,    1.2,   -0.2,
8048         -1.0,    1.0,   0.1,   -0.2,    1.2,
8049          1.0,    1.0,   0.1,    1.2,    1.2
8050     };
8051     memset(&caps, 0, sizeof(caps));
8052
8053     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8054     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8055     if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
8056     {
8057         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
8058         ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
8059                 "Card has conditional NP2 support without power of two restriction set\n");
8060     }
8061     else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
8062     {
8063         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
8064         return;
8065     }
8066     else
8067     {
8068         skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
8069         return;
8070     }
8071
8072     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8073     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8074
8075     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
8076     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8077
8078     memset(&rect, 0, sizeof(rect));
8079     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
8080     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8081     for(y = 0; y < 10; y++) {
8082         for(x = 0; x < 10; x++) {
8083             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
8084             if(x == 0 || x == 9 || y == 0 || y == 9) {
8085                 *dst = 0x00ff0000;
8086             } else {
8087                 *dst = 0x000000ff;
8088             }
8089         }
8090     }
8091     hr = IDirect3DTexture9_UnlockRect(texture, 0);
8092     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8093
8094     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8095     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8096     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
8097     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8098     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
8099     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8100     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8101     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8102
8103     hr = IDirect3DDevice9_BeginScene(device);
8104     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8105     if(SUCCEEDED(hr)) {
8106         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8107         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8108
8109         hr = IDirect3DDevice9_EndScene(device);
8110         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8111     }
8112
8113     color = getPixelColor(device,    1,  1);
8114     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
8115     color = getPixelColor(device, 639, 479);
8116     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
8117
8118     color = getPixelColor(device, 135, 101);
8119     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
8120     color = getPixelColor(device, 140, 101);
8121     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
8122     color = getPixelColor(device, 135, 105);
8123     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
8124     color = getPixelColor(device, 140, 105);
8125     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
8126
8127     color = getPixelColor(device, 135, 376);
8128     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
8129     color = getPixelColor(device, 140, 376);
8130     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
8131     color = getPixelColor(device, 135, 379);
8132     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
8133     color = getPixelColor(device, 140, 379);
8134     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
8135
8136     color = getPixelColor(device, 500, 101);
8137     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
8138     color = getPixelColor(device, 504, 101);
8139     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
8140     color = getPixelColor(device, 500, 105);
8141     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
8142     color = getPixelColor(device, 504, 105);
8143     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
8144
8145     color = getPixelColor(device, 500, 376);
8146     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
8147     color = getPixelColor(device, 504, 376);
8148     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
8149     color = getPixelColor(device, 500, 380);
8150     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
8151     color = getPixelColor(device, 504, 380);
8152     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
8153
8154     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8155
8156     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8157     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8158     IDirect3DTexture9_Release(texture);
8159 }
8160
8161 static void vFace_register_test(IDirect3DDevice9 *device)
8162 {
8163     HRESULT hr;
8164     DWORD color;
8165     const DWORD shader_code[] = {
8166         0xffff0300,                                                             /* ps_3_0                     */
8167         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8168         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
8169         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
8170         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
8171         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
8172         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8173         0x0000ffff                                                              /* END                        */
8174     };
8175     const DWORD vshader_code[] = {
8176         0xfffe0300,                                                             /* vs_3_0               */
8177         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8178         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8179         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8180         0x0000ffff                                                              /* end                  */
8181     };
8182     IDirect3DPixelShader9 *shader;
8183     IDirect3DVertexShader9 *vshader;
8184     IDirect3DTexture9 *texture;
8185     IDirect3DSurface9 *surface, *backbuffer;
8186     const float quad[] = {
8187         -1.0,   -1.0,   0.1,
8188          1.0,   -1.0,   0.1,
8189         -1.0,    0.0,   0.1,
8190
8191          1.0,   -1.0,   0.1,
8192          1.0,    0.0,   0.1,
8193         -1.0,    0.0,   0.1,
8194
8195         -1.0,    0.0,   0.1,
8196         -1.0,    1.0,   0.1,
8197          1.0,    0.0,   0.1,
8198
8199          1.0,    0.0,   0.1,
8200         -1.0,    1.0,   0.1,
8201          1.0,    1.0,   0.1,
8202     };
8203     const float blit[] = {
8204          0.0,   -1.0,   0.1,    0.0,    0.0,
8205          1.0,   -1.0,   0.1,    1.0,    0.0,
8206          0.0,    1.0,   0.1,    0.0,    1.0,
8207          1.0,    1.0,   0.1,    1.0,    1.0,
8208     };
8209
8210     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8211     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8212     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8213     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8214     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8215     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8216     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8217     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8218     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8219     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8220     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8221     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8222     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8223     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8224     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8225     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8226
8227     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8228     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8229
8230     hr = IDirect3DDevice9_BeginScene(device);
8231     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8232     if(SUCCEEDED(hr)) {
8233         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8234         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8235         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8236         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8237         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8238         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8239         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8240         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8241         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8242         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8243         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8244
8245         /* Blit the texture onto the back buffer to make it visible */
8246         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8247         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
8248         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8249         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8250         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8251         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8252         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8253         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8254         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8255         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8256         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8257         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8258
8259         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8260         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8261
8262         hr = IDirect3DDevice9_EndScene(device);
8263         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8264     }
8265
8266     color = getPixelColor(device, 160, 360);
8267     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8268     color = getPixelColor(device, 160, 120);
8269     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8270     color = getPixelColor(device, 480, 360);
8271     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8272     color = getPixelColor(device, 480, 120);
8273     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8274     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8275     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8276
8277     IDirect3DDevice9_SetTexture(device, 0, NULL);
8278     IDirect3DPixelShader9_Release(shader);
8279     IDirect3DVertexShader9_Release(vshader);
8280     IDirect3DSurface9_Release(surface);
8281     IDirect3DSurface9_Release(backbuffer);
8282     IDirect3DTexture9_Release(texture);
8283 }
8284
8285 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8286 {
8287     HRESULT hr;
8288     DWORD color;
8289     int i;
8290     D3DCAPS9 caps;
8291     BOOL L6V5U5_supported = FALSE;
8292     IDirect3DTexture9 *tex1, *tex2;
8293     D3DLOCKED_RECT locked_rect;
8294
8295     static const float quad[][7] = {
8296         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8297         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8298         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8299         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8300     };
8301
8302     static const D3DVERTEXELEMENT9 decl_elements[] = {
8303         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8304         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8305         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8306         D3DDECL_END()
8307     };
8308
8309     /* use asymmetric matrix to test loading */
8310     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8311     float scale, offset;
8312
8313     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8314     IDirect3DTexture9           *texture            = NULL;
8315
8316     memset(&caps, 0, sizeof(caps));
8317     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8318     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8319     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8320         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8321         return;
8322     } else {
8323         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8324          * They report that it is not supported, but after that bump mapping works properly. So just test
8325          * if the format is generally supported, and check the BUMPENVMAP flag
8326          */
8327         IDirect3D9 *d3d9;
8328
8329         IDirect3DDevice9_GetDirect3D(device, &d3d9);
8330         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8331                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8332         L6V5U5_supported = SUCCEEDED(hr);
8333         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8334                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8335         IDirect3D9_Release(d3d9);
8336         if(FAILED(hr)) {
8337             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8338             return;
8339         }
8340     }
8341
8342     /* Generate the textures */
8343     generate_bumpmap_textures(device);
8344
8345     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8346     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8347     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8348     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8349     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8350     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8351     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8352     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8353
8354     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8355     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8356     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8357     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8358     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8359     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8360
8361     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8362     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8363     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8364     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8365     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8366     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8367
8368     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8369     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8370
8371     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8372     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8373
8374     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8375     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8376
8377
8378     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8379     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8380     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8381     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8382
8383     hr = IDirect3DDevice9_BeginScene(device);
8384     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8385
8386     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8387     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8388
8389     hr = IDirect3DDevice9_EndScene(device);
8390     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8391
8392     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8393      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8394      * But since testing the color match is not the purpose of the test don't be too picky
8395      */
8396     color = getPixelColor(device, 320-32, 240);
8397     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8398     color = getPixelColor(device, 320+32, 240);
8399     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8400     color = getPixelColor(device, 320, 240-32);
8401     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8402     color = getPixelColor(device, 320, 240+32);
8403     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8404     color = getPixelColor(device, 320, 240);
8405     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8406     color = getPixelColor(device, 320+32, 240+32);
8407     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8408     color = getPixelColor(device, 320-32, 240+32);
8409     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8410     color = getPixelColor(device, 320+32, 240-32);
8411     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8412     color = getPixelColor(device, 320-32, 240-32);
8413     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8414     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8415     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8416
8417     for(i = 0; i < 2; i++) {
8418         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8419         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8420         IDirect3DTexture9_Release(texture); /* For the GetTexture */
8421         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8422         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8423         IDirect3DTexture9_Release(texture); /* To destroy it */
8424     }
8425
8426     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8427         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8428         goto cleanup;
8429     }
8430     if(L6V5U5_supported == FALSE) {
8431         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8432         goto cleanup;
8433     }
8434
8435     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8436     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8437     /* This test only tests the luminance part. The bumpmapping part was already tested above and
8438      * would only make this test more complicated
8439      */
8440     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8441     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8442     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8443     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8444
8445     memset(&locked_rect, 0, sizeof(locked_rect));
8446     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8447     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8448     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8449     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8450     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8451
8452     memset(&locked_rect, 0, sizeof(locked_rect));
8453     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8454     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8455     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8456     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8457     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8458
8459     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8460     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8461     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8462     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8463
8464     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8465     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8466     scale = 2.0;
8467     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8468     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8469     offset = 0.1;
8470     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8471     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8472
8473     hr = IDirect3DDevice9_BeginScene(device);
8474     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8475     if(SUCCEEDED(hr)) {
8476         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8477         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8478         hr = IDirect3DDevice9_EndScene(device);
8479         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8480     }
8481
8482     color = getPixelColor(device, 320, 240);
8483     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
8484      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
8485      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8486      */
8487     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8488     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8489     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8490
8491     /* Check a result scale factor > 1.0 */
8492     scale = 10;
8493     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8494     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8495     offset = 10;
8496     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8497     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8498
8499     hr = IDirect3DDevice9_BeginScene(device);
8500     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8501     if(SUCCEEDED(hr)) {
8502         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8503         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8504         hr = IDirect3DDevice9_EndScene(device);
8505         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8506     }
8507     color = getPixelColor(device, 320, 240);
8508     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8509     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8510     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8511
8512     /* Check clamping in the scale factor calculation */
8513     scale = 1000;
8514     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8515     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8516     offset = -1;
8517     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8518     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8519
8520     hr = IDirect3DDevice9_BeginScene(device);
8521     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8522     if(SUCCEEDED(hr)) {
8523         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8524         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8525         hr = IDirect3DDevice9_EndScene(device);
8526         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8527     }
8528     color = getPixelColor(device, 320, 240);
8529     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8530     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8531     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8532
8533     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8534     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8535     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8536     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8537
8538     IDirect3DTexture9_Release(tex1);
8539     IDirect3DTexture9_Release(tex2);
8540
8541 cleanup:
8542     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8543     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8544     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8545     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8546
8547     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8548     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8549     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8550 }
8551
8552 static void stencil_cull_test(IDirect3DDevice9 *device) {
8553     HRESULT hr;
8554     IDirect3DSurface9 *depthstencil = NULL;
8555     D3DSURFACE_DESC desc;
8556     float quad1[] = {
8557         -1.0,   -1.0,   0.1,
8558          0.0,   -1.0,   0.1,
8559         -1.0,    0.0,   0.1,
8560          0.0,    0.0,   0.1,
8561     };
8562     float quad2[] = {
8563          0.0,   -1.0,   0.1,
8564          1.0,   -1.0,   0.1,
8565          0.0,    0.0,   0.1,
8566          1.0,    0.0,   0.1,
8567     };
8568     float quad3[] = {
8569         0.0,    0.0,   0.1,
8570         1.0,    0.0,   0.1,
8571         0.0,    1.0,   0.1,
8572         1.0,    1.0,   0.1,
8573     };
8574     float quad4[] = {
8575         -1.0,    0.0,   0.1,
8576          0.0,    0.0,   0.1,
8577         -1.0,    1.0,   0.1,
8578          0.0,    1.0,   0.1,
8579     };
8580     struct vertex painter[] = {
8581        {-1.0,   -1.0,   0.0,    0x00000000},
8582        { 1.0,   -1.0,   0.0,    0x00000000},
8583        {-1.0,    1.0,   0.0,    0x00000000},
8584        { 1.0,    1.0,   0.0,    0x00000000},
8585     };
8586     WORD indices_cw[]  = {0, 1, 3};
8587     WORD indices_ccw[] = {0, 2, 3};
8588     unsigned int i;
8589     DWORD color;
8590
8591     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8592     if(depthstencil == NULL) {
8593         skip("No depth stencil buffer\n");
8594         return;
8595     }
8596     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8597     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8598     IDirect3DSurface9_Release(depthstencil);
8599     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8600         skip("No 4 or 8 bit stencil surface\n");
8601         return;
8602     }
8603
8604     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8605     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8606     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8607     ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
8608
8609     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8610     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8611     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8612     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8613     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8614     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8615     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8616     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8617
8618     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8619     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8620     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8621     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8622     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8623     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8624
8625     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8626     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8627     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8628     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8629
8630     /* First pass: Fill the stencil buffer with some values... */
8631     hr = IDirect3DDevice9_BeginScene(device);
8632     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8633     if(SUCCEEDED(hr))
8634     {
8635         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8636         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8637         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8638                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8639         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8640         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8641                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8642         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8643
8644         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8645         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8646         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8647         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8648         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8649                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8650         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8651         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8652                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8653         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8654
8655         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8656         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8657         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8658                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8659         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8660         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8661                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8662         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8663
8664         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8665         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8666         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8667                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8668         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8669         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8670                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8671         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8672
8673         hr = IDirect3DDevice9_EndScene(device);
8674         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8675     }
8676
8677     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8678     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8679     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8680     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8681     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8682     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8683     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8684     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8685     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8686     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8687     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8688     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8689
8690     /* 2nd pass: Make the stencil values visible */
8691     hr = IDirect3DDevice9_BeginScene(device);
8692     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8693     if(SUCCEEDED(hr))
8694     {
8695         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8696         ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8697         for (i = 0; i < 16; ++i)
8698         {
8699             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8700             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8701
8702             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8703             painter[1].diffuse = (i * 16);
8704             painter[2].diffuse = (i * 16);
8705             painter[3].diffuse = (i * 16);
8706             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8707             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8708         }
8709         hr = IDirect3DDevice9_EndScene(device);
8710         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8711     }
8712
8713     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8714     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8715
8716     color = getPixelColor(device, 160, 420);
8717     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8718     color = getPixelColor(device, 160, 300);
8719     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8720
8721     color = getPixelColor(device, 480, 420);
8722     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8723     color = getPixelColor(device, 480, 300);
8724     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8725
8726     color = getPixelColor(device, 160, 180);
8727     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8728     color = getPixelColor(device, 160, 60);
8729     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8730
8731     color = getPixelColor(device, 480, 180);
8732     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8733     color = getPixelColor(device, 480, 60);
8734     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8735
8736     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8737     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8738 }
8739
8740 static void vpos_register_test(IDirect3DDevice9 *device)
8741 {
8742     HRESULT hr;
8743     DWORD color;
8744     const DWORD shader_code[] = {
8745     0xffff0300,                                                             /* ps_3_0                     */
8746     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8747     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8748     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8749     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8750     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8751     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8752     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8753     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8754     0x0000ffff                                                              /* end                        */
8755     };
8756     const DWORD shader_frac_code[] = {
8757     0xffff0300,                                                             /* ps_3_0                     */
8758     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8759     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8760     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8761     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8762     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8763     0x0000ffff                                                              /* end                        */
8764     };
8765     const DWORD vshader_code[] = {
8766         0xfffe0300,                                                             /* vs_3_0               */
8767         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8768         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8769         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8770         0x0000ffff                                                              /* end                  */
8771     };
8772     IDirect3DVertexShader9 *vshader;
8773     IDirect3DPixelShader9 *shader, *shader_frac;
8774     IDirect3DSurface9 *surface = NULL, *backbuffer;
8775     const float quad[] = {
8776         -1.0,   -1.0,   0.1,    0.0,    0.0,
8777          1.0,   -1.0,   0.1,    1.0,    0.0,
8778         -1.0,    1.0,   0.1,    0.0,    1.0,
8779          1.0,    1.0,   0.1,    1.0,    1.0,
8780     };
8781     D3DLOCKED_RECT lr;
8782     float constant[4] = {1.0, 0.0, 320, 240};
8783     DWORD *pos;
8784
8785     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8786     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8787     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8788     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8789     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8790     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8791     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8792     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8793     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8794     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8795     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8796     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8797     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8798     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8799     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8800     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8801
8802     hr = IDirect3DDevice9_BeginScene(device);
8803     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8804     if(SUCCEEDED(hr)) {
8805         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8806         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8807         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8808         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8809         hr = IDirect3DDevice9_EndScene(device);
8810         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8811     }
8812
8813     /* This has to be pixel exact */
8814     color = getPixelColor(device, 319, 239);
8815     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8816     color = getPixelColor(device, 320, 239);
8817     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8818     color = getPixelColor(device, 319, 240);
8819     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8820     color = getPixelColor(device, 320, 240);
8821     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8822     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8823
8824     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8825                                              &surface, NULL);
8826     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8827     hr = IDirect3DDevice9_BeginScene(device);
8828     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8829     if(SUCCEEDED(hr)) {
8830         constant[2] = 16; constant[3] = 16;
8831         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8832         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8833         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8834         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8835         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8836         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8837         hr = IDirect3DDevice9_EndScene(device);
8838         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8839     }
8840     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8841     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8842
8843     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8844     color = *pos & 0x00ffffff;
8845     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8846     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8847     color = *pos & 0x00ffffff;
8848     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8849     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8850     color = *pos & 0x00ffffff;
8851     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8852     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8853     color = *pos & 0x00ffffff;
8854     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8855
8856     hr = IDirect3DSurface9_UnlockRect(surface);
8857     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8858
8859     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8860      * have full control over the multisampling setting inside this test
8861      */
8862     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8863     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8864     hr = IDirect3DDevice9_BeginScene(device);
8865     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8866     if(SUCCEEDED(hr)) {
8867         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8868         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8869         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8870         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8871         hr = IDirect3DDevice9_EndScene(device);
8872         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8873     }
8874     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8875     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8876
8877     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8878     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8879
8880     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8881     color = *pos & 0x00ffffff;
8882     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8883
8884     hr = IDirect3DSurface9_UnlockRect(surface);
8885     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8886
8887     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8888     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8889     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8890     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8891     IDirect3DPixelShader9_Release(shader);
8892     IDirect3DPixelShader9_Release(shader_frac);
8893     IDirect3DVertexShader9_Release(vshader);
8894     if(surface) IDirect3DSurface9_Release(surface);
8895     IDirect3DSurface9_Release(backbuffer);
8896 }
8897
8898 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8899 {
8900     D3DCOLOR color;
8901
8902     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8903     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8904     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8905     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8906     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8907
8908     ++r;
8909     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8910     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8911     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8912     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8913     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8914
8915     return TRUE;
8916 }
8917
8918 static void pointsize_test(IDirect3DDevice9 *device)
8919 {
8920     HRESULT hr;
8921     D3DCAPS9 caps;
8922     D3DMATRIX matrix;
8923     D3DMATRIX identity;
8924     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8925     DWORD color;
8926     IDirect3DSurface9 *rt, *backbuffer;
8927     IDirect3DTexture9 *tex1, *tex2;
8928     RECT rect = {0, 0, 128, 128};
8929     D3DLOCKED_RECT lr;
8930     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8931                                 0x00000000, 0x00000000};
8932     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8933                                 0x00000000, 0x0000ff00};
8934
8935     const float vertices[] = {
8936         64,     64,     0.1,
8937         128,    64,     0.1,
8938         192,    64,     0.1,
8939         256,    64,     0.1,
8940         320,    64,     0.1,
8941         384,    64,     0.1,
8942         448,    64,     0.1,
8943         512,    64,     0.1,
8944     };
8945
8946     /* 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 */
8947     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;
8948     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;
8949     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;
8950     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;
8951
8952     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;
8953     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;
8954     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;
8955     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;
8956
8957     memset(&caps, 0, sizeof(caps));
8958     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8959     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8960     if(caps.MaxPointSize < 32.0) {
8961         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8962         return;
8963     }
8964
8965     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8966     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8967     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8968     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8969     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8970     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8971     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8972     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8973
8974     hr = IDirect3DDevice9_BeginScene(device);
8975     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8976     if (SUCCEEDED(hr))
8977     {
8978         ptsize = 15.0;
8979         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8980         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8981         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8982         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8983
8984         ptsize = 31.0;
8985         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8986         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8987         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8988         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8989
8990         ptsize = 30.75;
8991         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8992         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8993         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8994         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8995
8996         if (caps.MaxPointSize >= 63.0)
8997         {
8998             ptsize = 63.0;
8999             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9000             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9001             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
9002             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9003
9004             ptsize = 62.75;
9005             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9006             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9007             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
9008             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9009         }
9010
9011         ptsize = 1.0;
9012         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9013         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9014         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
9015         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9016
9017         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
9018         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
9019         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
9020         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
9021
9022         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
9023         ptsize = 15.0;
9024         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9025         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9026         ptsize = 1.0;
9027         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
9028         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9029         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
9030         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9031
9032         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
9033         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9034
9035         /* pointsize < pointsize_min < pointsize_max?
9036          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
9037         ptsize = 1.0;
9038         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9039         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9040         ptsize = 15.0;
9041         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
9042         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9043         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
9044         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9045
9046         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
9047         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9048
9049         hr = IDirect3DDevice9_EndScene(device);
9050         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
9051     }
9052
9053     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
9054     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
9055     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
9056
9057     if (caps.MaxPointSize >= 63.0)
9058     {
9059         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
9060         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
9061     }
9062
9063     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
9064     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
9065     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
9066     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
9067     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
9068
9069     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9070
9071     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
9072      * generates texture coordinates for the point(result: Yes, it does)
9073      *
9074      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
9075      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
9076      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
9077      */
9078     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
9079     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9080
9081     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
9082     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9083     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9084     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9085     memset(&lr, 0, sizeof(lr));
9086     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
9087     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9088     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
9089     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9090     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9091     memset(&lr, 0, sizeof(lr));
9092     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
9093     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9094     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
9095     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9096     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9097     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9098     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9099     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9100     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9101     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9102     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9103     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9104     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9105     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9106     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9107     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9108     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9109     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9110     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9111
9112     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
9113     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9114     ptsize = 32.0;
9115     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9116     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9117
9118     hr = IDirect3DDevice9_BeginScene(device);
9119     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9120     if(SUCCEEDED(hr))
9121     {
9122         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9123         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9124         hr = IDirect3DDevice9_EndScene(device);
9125         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9126     }
9127
9128     color = getPixelColor(device, 64-4, 64-4);
9129     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
9130     color = getPixelColor(device, 64-4, 64+4);
9131     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
9132     color = getPixelColor(device, 64+4, 64+4);
9133     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
9134     color = getPixelColor(device, 64+4, 64-4);
9135     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
9136     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9137
9138     U(matrix).m[0][0] =  1.0f / 64.0f;
9139     U(matrix).m[1][1] = -1.0f / 64.0f;
9140     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
9141     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
9142
9143     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
9144     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
9145
9146     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
9147             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
9148     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
9149
9150     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
9151     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9152     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
9153     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
9154
9155     hr = IDirect3DDevice9_BeginScene(device);
9156     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9157     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9158     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9159     hr = IDirect3DDevice9_EndScene(device);
9160     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9161
9162     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
9163     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
9164     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9165     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9166     IDirect3DSurface9_Release(backbuffer);
9167     IDirect3DSurface9_Release(rt);
9168
9169     color = getPixelColor(device, 64-4, 64-4);
9170     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
9171             "Expected color 0x00ff0000, got 0x%08x.\n", color);
9172     color = getPixelColor(device, 64+4, 64-4);
9173     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
9174             "Expected color 0x00ffff00, got 0x%08x.\n", color);
9175     color = getPixelColor(device, 64-4, 64+4);
9176     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
9177             "Expected color 0x00000000, got 0x%08x.\n", color);
9178     color = getPixelColor(device, 64+4, 64+4);
9179     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9180             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9181
9182     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9183     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9184
9185     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9186     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9187     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9188     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9189     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9190     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9191     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9192     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9193     IDirect3DTexture9_Release(tex1);
9194     IDirect3DTexture9_Release(tex2);
9195
9196     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9197     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9198     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9199     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9200     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9201     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9202 }
9203
9204 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9205 {
9206     static const DWORD vshader_code[] =
9207     {
9208         0xfffe0300,                                                             /* vs_3_0                     */
9209         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0            */
9210         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0            */
9211         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                 */
9212         0x0000ffff                                                              /* end                        */
9213     };
9214     static const DWORD pshader_code1[] =
9215     {
9216         0xffff0300,                                                             /* ps_3_0                     */
9217         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9218         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
9219         0x0000ffff                                                              /* end                        */
9220     };
9221     static const DWORD pshader_code2[] =
9222     {
9223         0xffff0300,                                                             /* ps_3_0                     */
9224         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9225         0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
9226         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
9227         0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1                */
9228         0x0000ffff                                                              /* end                        */
9229     };
9230
9231     HRESULT hr;
9232     IDirect3DVertexShader9 *vs;
9233     IDirect3DPixelShader9 *ps1, *ps2;
9234     IDirect3DTexture9 *tex1, *tex2;
9235     IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
9236     D3DCAPS9 caps;
9237     DWORD color;
9238     UINT i, j;
9239     float quad[] = {
9240        -1.0,   -1.0,    0.1,
9241         1.0,   -1.0,    0.1,
9242        -1.0,    1.0,    0.1,
9243         1.0,    1.0,    0.1,
9244     };
9245     float texquad[] = {
9246        -1.0,   -1.0,    0.1,    0.0,    0.0,
9247         0.0,   -1.0,    0.1,    1.0,    0.0,
9248        -1.0,    1.0,    0.1,    0.0,    1.0,
9249         0.0,    1.0,    0.1,    1.0,    1.0,
9250
9251         0.0,   -1.0,    0.1,    0.0,    0.0,
9252         1.0,   -1.0,    0.1,    1.0,    0.0,
9253         0.0,    1.0,    0.1,    0.0,    1.0,
9254         1.0,    1.0,    0.1,    1.0,    1.0,
9255     };
9256
9257     memset(&caps, 0, sizeof(caps));
9258     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9259     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9260     if(caps.NumSimultaneousRTs < 2) {
9261         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9262         return;
9263     }
9264
9265     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9266     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9267
9268     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
9269             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
9270     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
9271
9272     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9273             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9274     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9275     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9276             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9277     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9278     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
9279     ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
9280     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
9281     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9282     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
9283     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9284
9285     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9286     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9287     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9288     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9289     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9290     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9291
9292     hr = IDirect3DDevice9_SetVertexShader(device, vs);
9293     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9294     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9295     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9296     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9297     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9298     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9299     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9300
9301     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
9302     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9303     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9304     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9305     color = getPixelColorFromSurface(readback, 8, 8);
9306     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9307             "Expected color 0x000000ff, got 0x%08x.\n", color);
9308     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9309     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9310     color = getPixelColorFromSurface(readback, 8, 8);
9311     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9312             "Expected color 0x000000ff, got 0x%08x.\n", color);
9313
9314     /* Render targets not written by the pixel shader should be unmodified. */
9315     hr = IDirect3DDevice9_SetPixelShader(device, ps1);
9316     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9317     hr = IDirect3DDevice9_BeginScene(device);
9318     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9319     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9320     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9321     hr = IDirect3DDevice9_EndScene(device);
9322     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9323     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9324     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9325     color = getPixelColorFromSurface(readback, 8, 8);
9326     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9327             "Expected color 0xff00ff00, got 0x%08x.\n", color);
9328     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9329     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9330     for (i = 6; i < 10; ++i)
9331     {
9332         for (j = 6; j < 10; ++j)
9333         {
9334             color = getPixelColorFromSurface(readback, j, i);
9335             ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9336                     "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
9337         }
9338     }
9339
9340     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9341     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9342     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9343     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9344     color = getPixelColorFromSurface(readback, 8, 8);
9345     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9346             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9347     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9348     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9349     color = getPixelColorFromSurface(readback, 8, 8);
9350     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9351             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9352
9353     hr = IDirect3DDevice9_SetPixelShader(device, ps2);
9354     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9355
9356     hr = IDirect3DDevice9_BeginScene(device);
9357     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9358     if(SUCCEEDED(hr)) {
9359         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9360         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9361
9362         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9363         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9364         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9365         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9366         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9367         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9368         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9369         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9370         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9371         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9372
9373         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9374         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9375         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9376         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9377
9378         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9379         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9380         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9381         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9382
9383         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9384         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9385
9386         hr = IDirect3DDevice9_EndScene(device);
9387         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9388     }
9389
9390     color = getPixelColor(device, 160, 240);
9391     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9392     color = getPixelColor(device, 480, 240);
9393     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9394     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9395
9396     IDirect3DPixelShader9_Release(ps2);
9397     IDirect3DPixelShader9_Release(ps1);
9398     IDirect3DVertexShader9_Release(vs);
9399     IDirect3DTexture9_Release(tex1);
9400     IDirect3DTexture9_Release(tex2);
9401     IDirect3DSurface9_Release(surf1);
9402     IDirect3DSurface9_Release(surf2);
9403     IDirect3DSurface9_Release(backbuf);
9404     IDirect3DSurface9_Release(readback);
9405 }
9406
9407 struct formats {
9408     const char *fmtName;
9409     D3DFORMAT textureFormat;
9410     DWORD resultColorBlending;
9411     DWORD resultColorNoBlending;
9412 };
9413
9414 static const struct formats test_formats[] = {
9415   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9416   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9417   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9418   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9419   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9420   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9421   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9422   { NULL, 0 }
9423 };
9424
9425 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9426 {
9427     HRESULT hr;
9428     IDirect3DTexture9 *offscreenTexture = NULL;
9429     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9430     IDirect3D9 *d3d = NULL;
9431     DWORD color;
9432     DWORD r0, g0, b0, r1, g1, b1;
9433     int fmt_index;
9434
9435     static const float quad[][5] = {
9436         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9437         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
9438         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9439         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
9440     };
9441
9442     /* Quad with R=0x10, G=0x20 */
9443     static const struct vertex quad1[] = {
9444         {-1.0f, -1.0f, 0.1f, 0x80102000},
9445         {-1.0f,  1.0f, 0.1f, 0x80102000},
9446         { 1.0f, -1.0f, 0.1f, 0x80102000},
9447         { 1.0f,  1.0f, 0.1f, 0x80102000},
9448     };
9449
9450     /* Quad with R=0x20, G=0x10 */
9451     static const struct vertex quad2[] = {
9452         {-1.0f, -1.0f, 0.1f, 0x80201000},
9453         {-1.0f,  1.0f, 0.1f, 0x80201000},
9454         { 1.0f, -1.0f, 0.1f, 0x80201000},
9455         { 1.0f,  1.0f, 0.1f, 0x80201000},
9456     };
9457
9458     IDirect3DDevice9_GetDirect3D(device, &d3d);
9459
9460     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9461     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9462     if(!backbuffer) {
9463         goto out;
9464     }
9465
9466     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9467     {
9468         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9469
9470         if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9471                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
9472         {
9473             skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
9474             continue;
9475         }
9476
9477         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9478         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9479
9480         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9481         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9482         if(!offscreenTexture) {
9483             continue;
9484         }
9485
9486         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9487         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9488         if(!offscreen) {
9489             continue;
9490         }
9491
9492         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9493         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9494
9495         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9496         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9497         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9498         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9499         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9500         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9501         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9502         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9503         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9504         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9505
9506         /* Below we will draw two quads with different colors and try to blend them together.
9507          * The result color is compared with the expected outcome.
9508          */
9509         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9510             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9511             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9512             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9513             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9514
9515             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9516             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9517
9518             /* Draw a quad using color 0x0010200 */
9519             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9520             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9521             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9522             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9523             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9524             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9525
9526             /* Draw a quad using color 0x0020100 */
9527             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9528             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9529             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9530             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9531             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9532             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9533
9534             /* We don't want to blend the result on the backbuffer */
9535             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9536             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9537
9538             /* Prepare rendering the 'blended' texture quad to the backbuffer */
9539             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9540             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9541             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9542             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9543
9544             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9545             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9546
9547             /* This time with the texture */
9548             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9549             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9550
9551             IDirect3DDevice9_EndScene(device);
9552         }
9553
9554         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9555             /* Compare the color of the center quad with our expectation */
9556             color = getPixelColor(device, 320, 240);
9557             r0 = (color & 0x00ff0000) >> 16;
9558             g0 = (color & 0x0000ff00) >>  8;
9559             b0 = (color & 0x000000ff) >>  0;
9560
9561             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9562             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9563             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9564
9565             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9566                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9567                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9568                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9569         } else {
9570             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9571              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9572              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9573             color = getPixelColor(device, 320, 240);
9574             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);
9575         }
9576         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9577
9578         IDirect3DDevice9_SetTexture(device, 0, NULL);
9579         if(offscreenTexture) {
9580             IDirect3DTexture9_Release(offscreenTexture);
9581         }
9582         if(offscreen) {
9583             IDirect3DSurface9_Release(offscreen);
9584         }
9585     }
9586
9587 out:
9588     /* restore things */
9589     if(backbuffer) {
9590         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9591         IDirect3DSurface9_Release(backbuffer);
9592     }
9593 }
9594
9595 static void tssargtemp_test(IDirect3DDevice9 *device)
9596 {
9597     HRESULT hr;
9598     DWORD color;
9599     static const struct vertex quad[] = {
9600         {-1.0,     -1.0,    0.1,    0x00ff0000},
9601         { 1.0,     -1.0,    0.1,    0x00ff0000},
9602         {-1.0,      1.0,    0.1,    0x00ff0000},
9603         { 1.0,      1.0,    0.1,    0x00ff0000}
9604     };
9605     D3DCAPS9 caps;
9606
9607     memset(&caps, 0, sizeof(caps));
9608     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9609     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9610     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9611         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9612         return;
9613     }
9614
9615     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9616     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9617
9618     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9619     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9620     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9621     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9622
9623     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9624     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9625     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9626     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9627     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9628     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9629
9630     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9631     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9632     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9633     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9634     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9635     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9636
9637     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9638     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9639
9640     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9641     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9642     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9643     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9644
9645     hr = IDirect3DDevice9_BeginScene(device);
9646     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9647     if(SUCCEEDED(hr)) {
9648         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9649         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9650         hr = IDirect3DDevice9_EndScene(device);
9651         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9652     }
9653     color = getPixelColor(device, 320, 240);
9654     ok(color == 0x00ffff00, "TSSARGTEMP test returned color 0x%08x, expected 0x00ffff00\n", color);
9655     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9656
9657     /* Set stage 1 back to default */
9658     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9659     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9660     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9661     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9662     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9663     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9664     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9665     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9666     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9667     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9668 }
9669
9670 struct testdata
9671 {
9672     DWORD idxVertex; /* number of instances in the first stream */
9673     DWORD idxColor; /* number of instances in the second stream */
9674     DWORD idxInstance; /* should be 1 ?? */
9675     DWORD color1; /* color 1 instance */
9676     DWORD color2; /* color 2 instance */
9677     DWORD color3; /* color 3 instance */
9678     DWORD color4; /* color 4 instance */
9679     WORD strVertex; /* specify which stream to use 0-2*/
9680     WORD strColor;
9681     WORD strInstance;
9682 };
9683
9684 static const struct testdata testcases[]=
9685 {
9686     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9687     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9688     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9689     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9690     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  4 */
9691     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9692     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9693     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9694     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  8 */
9695     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /*  9 */
9696     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9697     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9698     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9699     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9700 /*
9701     This draws one instance on some machines, no instance on others
9702     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9703 */
9704 /*
9705     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9706     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9707 */
9708 };
9709
9710 /* Drawing Indexed Geometry with instances*/
9711 static void stream_test(IDirect3DDevice9 *device)
9712 {
9713     IDirect3DVertexBuffer9 *vb = NULL;
9714     IDirect3DVertexBuffer9 *vb2 = NULL;
9715     IDirect3DVertexBuffer9 *vb3 = NULL;
9716     IDirect3DIndexBuffer9 *ib = NULL;
9717     IDirect3DVertexDeclaration9 *pDecl = NULL;
9718     IDirect3DVertexShader9 *shader = NULL;
9719     HRESULT hr;
9720     BYTE *data;
9721     DWORD color;
9722     DWORD ind;
9723     unsigned i;
9724
9725     const DWORD shader_code[] =
9726     {
9727         0xfffe0101,                                     /* vs_1_1 */
9728         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9729         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9730         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9731         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9732         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9733         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9734         0x0000ffff
9735     };
9736
9737     const float quad[][3] =
9738     {
9739         {-0.5f, -0.5f,  1.1f}, /*0 */
9740         {-0.5f,  0.5f,  1.1f}, /*1 */
9741         { 0.5f, -0.5f,  1.1f}, /*2 */
9742         { 0.5f,  0.5f,  1.1f}, /*3 */
9743     };
9744
9745     const float vertcolor[][4] =
9746     {
9747         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9748         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9749         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9750         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9751     };
9752
9753     /* 4 position for 4 instances */
9754     const float instancepos[][3] =
9755     {
9756         {-0.6f,-0.6f, 0.0f},
9757         { 0.6f,-0.6f, 0.0f},
9758         { 0.6f, 0.6f, 0.0f},
9759         {-0.6f, 0.6f, 0.0f},
9760     };
9761
9762     short indices[] = {0, 1, 2, 1, 2, 3};
9763
9764     D3DVERTEXELEMENT9 decl[] =
9765     {
9766         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9767         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9768         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9769         D3DDECL_END()
9770     };
9771
9772     /* set the default value because it isn't done in wine? */
9773     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9774     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9775
9776     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9777     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9778     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9779
9780     /* check wrong cases */
9781     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9782     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9783     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9784     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9785     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9786     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9787     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9788     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9789     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9790     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9791     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9792     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9793     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9794     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9795     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9796     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9797     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9798     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9799     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9800     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9801
9802     /* set the default value back */
9803     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9804     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9805
9806     /* create all VertexBuffers*/
9807     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9808     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9809     if(!vb) {
9810         skip("Failed to create a vertex buffer\n");
9811         return;
9812     }
9813     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9814     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9815     if(!vb2) {
9816         skip("Failed to create a vertex buffer\n");
9817         goto out;
9818     }
9819     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9820     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9821     if(!vb3) {
9822         skip("Failed to create a vertex buffer\n");
9823         goto out;
9824     }
9825
9826     /* create IndexBuffer*/
9827     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9828     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9829     if(!ib) {
9830         skip("Failed to create a index buffer\n");
9831         goto out;
9832     }
9833
9834     /* copy all Buffers (Vertex + Index)*/
9835     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9836     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9837     memcpy(data, quad, sizeof(quad));
9838     hr = IDirect3DVertexBuffer9_Unlock(vb);
9839     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9840     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9841     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9842     memcpy(data, vertcolor, sizeof(vertcolor));
9843     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9844     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9845     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9846     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9847     memcpy(data, instancepos, sizeof(instancepos));
9848     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9849     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9850     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9851     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9852     memcpy(data, indices, sizeof(indices));
9853     hr = IDirect3DIndexBuffer9_Unlock(ib);
9854     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9855
9856     /* create VertexShader */
9857     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9858     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9859     if(!shader) {
9860         skip("Failed to create a vetex shader\n");
9861         goto out;
9862     }
9863
9864     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9865     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9866
9867     hr = IDirect3DDevice9_SetIndices(device, ib);
9868     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9869
9870     /* run all tests */
9871     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9872     {
9873         struct testdata act = testcases[i];
9874         decl[0].Stream = act.strVertex;
9875         decl[1].Stream = act.strColor;
9876         decl[2].Stream = act.strInstance;
9877         /* create VertexDeclarations */
9878         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9879         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9880
9881         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9882         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9883
9884         hr = IDirect3DDevice9_BeginScene(device);
9885         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9886         if(SUCCEEDED(hr))
9887         {
9888             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9889             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9890
9891             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9892             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9893             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9894             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9895
9896             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9897             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9898             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9899             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9900
9901             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9902             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9903             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9904             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9905
9906             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9907             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9908             hr = IDirect3DDevice9_EndScene(device);
9909             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9910
9911             /* set all StreamSource && StreamSourceFreq back to default */
9912             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9913             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9914             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9915             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9916             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9917             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9918             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9919             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9920             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9921             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9922             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9923             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9924         }
9925
9926         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9927         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9928
9929         color = getPixelColor(device, 160, 360);
9930         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9931         color = getPixelColor(device, 480, 360);
9932         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9933         color = getPixelColor(device, 480, 120);
9934         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9935         color = getPixelColor(device, 160, 120);
9936         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9937
9938         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9939         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9940     }
9941
9942     hr = IDirect3DDevice9_SetIndices(device, NULL);
9943     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9944
9945 out:
9946     if(vb) IDirect3DVertexBuffer9_Release(vb);
9947     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9948     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9949     if(ib)IDirect3DIndexBuffer9_Release(ib);
9950     if(shader)IDirect3DVertexShader9_Release(shader);
9951 }
9952
9953 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9954     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9955     IDirect3DTexture9 *dsttex = NULL;
9956     HRESULT hr;
9957     DWORD color;
9958     D3DRECT r1 = {0,  0,  50,  50 };
9959     D3DRECT r2 = {50, 0,  100, 50 };
9960     D3DRECT r3 = {50, 50, 100, 100};
9961     D3DRECT r4 = {0,  50,  50, 100};
9962     const float quad[] = {
9963         -1.0,   -1.0,   0.1,    0.0,    0.0,
9964          1.0,   -1.0,   0.1,    1.0,    0.0,
9965         -1.0,    1.0,   0.1,    0.0,    1.0,
9966          1.0,    1.0,   0.1,    1.0,    1.0,
9967     };
9968
9969     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9970     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9971
9972     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9973     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9974     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9975     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9976
9977     if(!src || !dsttex) {
9978         skip("One or more test resources could not be created\n");
9979         goto cleanup;
9980     }
9981
9982     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9983     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9984
9985     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9986     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9987
9988     /* Clear the StretchRect destination for debugging */
9989     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9990     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9991     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9992     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9993
9994     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9995     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9996
9997     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9998     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9999     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
10000     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10001     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10002     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10003     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
10004     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10005
10006     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
10007      * the target -> texture GL blit path
10008      */
10009     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
10010     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
10011     IDirect3DSurface9_Release(dst);
10012
10013     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10014     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
10015
10016     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
10017     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
10018     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10019     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10020     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10021     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
10022     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10023     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
10024
10025     hr = IDirect3DDevice9_BeginScene(device);
10026     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
10027     if(SUCCEEDED(hr)) {
10028         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10029         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
10030         hr = IDirect3DDevice9_EndScene(device);
10031         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
10032     }
10033
10034     color = getPixelColor(device, 160, 360);
10035     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
10036     color = getPixelColor(device, 480, 360);
10037     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
10038     color = getPixelColor(device, 480, 120);
10039     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
10040     color = getPixelColor(device, 160, 120);
10041     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
10042     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10043     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10044
10045     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10046     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
10047     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10048     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
10049
10050 cleanup:
10051     if(src) IDirect3DSurface9_Release(src);
10052     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
10053     if(dsttex) IDirect3DTexture9_Release(dsttex);
10054 }
10055
10056 static void texop_test(IDirect3DDevice9 *device)
10057 {
10058     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
10059     IDirect3DTexture9 *texture = NULL;
10060     D3DLOCKED_RECT locked_rect;
10061     D3DCOLOR color;
10062     D3DCAPS9 caps;
10063     HRESULT hr;
10064     unsigned i;
10065
10066     static const struct {
10067         float x, y, z;
10068         float s, t;
10069         D3DCOLOR diffuse;
10070     } quad[] = {
10071         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10072         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10073         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10074         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
10075     };
10076
10077     static const D3DVERTEXELEMENT9 decl_elements[] = {
10078         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10079         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
10080         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
10081         D3DDECL_END()
10082     };
10083
10084     static const struct {
10085         D3DTEXTUREOP op;
10086         const char *name;
10087         DWORD caps_flag;
10088         D3DCOLOR result;
10089     } test_data[] = {
10090         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10091         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
10092         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
10093         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
10094         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10095         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10096         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
10097         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10098         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10099         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10100         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10101         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
10102         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
10103         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10104         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10105         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
10106         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
10107         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10108         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
10109         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
10110         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
10111         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
10112         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
10113     };
10114
10115     memset(&caps, 0, sizeof(caps));
10116     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10117     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10118
10119     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
10120     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
10121     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
10122     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
10123
10124     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10125     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10126     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10127     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10128     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
10129     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10130     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10131     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10132     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10133
10134     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
10135     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10136     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10137     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10138     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10139     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10140
10141     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10142     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10143
10144     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10145     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10146     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
10147     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10148     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
10149     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10150
10151     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10152     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10153
10154     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
10155     {
10156         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
10157         {
10158             skip("tex operation %s not supported\n", test_data[i].name);
10159             continue;
10160         }
10161
10162         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
10163         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
10164
10165         hr = IDirect3DDevice9_BeginScene(device);
10166         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10167
10168         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10169         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10170
10171         hr = IDirect3DDevice9_EndScene(device);
10172         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10173
10174         color = getPixelColor(device, 320, 240);
10175         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
10176                 test_data[i].name, color, test_data[i].result);
10177
10178         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10179         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10180     }
10181
10182     if (texture) IDirect3DTexture9_Release(texture);
10183     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
10184 }
10185
10186 static void yuv_color_test(IDirect3DDevice9 *device) {
10187     HRESULT hr;
10188     IDirect3DSurface9 *surface = NULL, *target = NULL;
10189     unsigned int fmt, i;
10190     D3DFORMAT format;
10191     const char *fmt_string;
10192     D3DLOCKED_RECT lr;
10193     IDirect3D9 *d3d;
10194     HRESULT color;
10195     DWORD ref_color_left, ref_color_right;
10196
10197     struct {
10198         DWORD in;           /* The input color */
10199         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
10200         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
10201         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
10202         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
10203     } test_data[] = {
10204     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
10205      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
10206      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
10207      * that
10208      */
10209       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
10210       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
10211       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
10212       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
10213       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
10214       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
10215       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
10216       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
10217       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
10218       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
10219       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
10220       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
10221       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
10222       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
10223
10224       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
10225       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
10226       { 0xff80ff80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
10227       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
10228     };
10229
10230     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
10231     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
10232     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
10233     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
10234
10235     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
10236     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10237
10238     for(fmt = 0; fmt < 2; fmt++) {
10239         if(fmt == 0) {
10240             format = D3DFMT_UYVY;
10241             fmt_string = "D3DFMT_UYVY";
10242         } else {
10243             format = D3DFMT_YUY2;
10244             fmt_string = "D3DFMT_YUY2";
10245         }
10246
10247         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
10248                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
10249                        */
10250         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
10251                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
10252             skip("%s is not supported\n", fmt_string);
10253             continue;
10254         }
10255
10256         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1
10257          * However, Nvidia Windows drivers have problems with 2x1 YUY2/UYVY surfaces, so use a 4x1 surface and
10258          * fill the second block with dummy data. If the surface has a size of 2x1, those drivers ignore the
10259          * second luminance value, resulting in an incorrect color in the right pixel. */
10260         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
10261         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
10262
10263         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
10264             if(fmt == 0) {
10265                 ref_color_left = test_data[i].uyvy_left;
10266                 ref_color_right = test_data[i].uyvy_right;
10267             } else {
10268                 ref_color_left = test_data[i].yuy2_left;
10269                 ref_color_right = test_data[i].yuy2_right;
10270             }
10271
10272             memset(&lr, 0, sizeof(lr));
10273             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
10274             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
10275             ((DWORD *) lr.pBits)[0] = test_data[i].in;
10276             ((DWORD *) lr.pBits)[1] = 0x00800080;
10277             hr = IDirect3DSurface9_UnlockRect(surface);
10278             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10279
10280             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10281             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10282             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10283             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10284
10285             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10286              * prevent running into precision problems, read a far left and far right pixel. In the future we may
10287              * want to add tests for the filtered pixels as well.
10288              *
10289              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10290              * differently, so we need a max diff of 18
10291              */
10292             color = getPixelColor(device, 1, 240);
10293             ok(color_match(color, ref_color_left, 18),
10294                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10295                test_data[i].in, color, ref_color_left, fmt_string);
10296             color = getPixelColor(device, 318, 240);
10297             ok(color_match(color, ref_color_right, 18),
10298                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10299                test_data[i].in, color, ref_color_right, fmt_string);
10300             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10301             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10302         }
10303         IDirect3DSurface9_Release(surface);
10304     }
10305
10306     IDirect3DSurface9_Release(target);
10307     IDirect3D9_Release(d3d);
10308 }
10309
10310 static void texop_range_test(IDirect3DDevice9 *device)
10311 {
10312     static const struct {
10313         float x, y, z;
10314         D3DCOLOR diffuse;
10315     } quad[] = {
10316         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10317         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10318         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10319         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10320     };
10321     HRESULT hr;
10322     IDirect3DTexture9 *texture;
10323     D3DLOCKED_RECT locked_rect;
10324     D3DCAPS9 caps;
10325     DWORD color;
10326
10327     /* We need ADD and SUBTRACT operations */
10328     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10329     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10330     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10331         skip("D3DTOP_ADD is not supported, skipping value range test\n");
10332         return;
10333     }
10334     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10335         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10336         return;
10337     }
10338
10339     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10340     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10341     /* Stage 1: result = diffuse(=1.0) + diffuse
10342      * stage 2: result = result - tfactor(= 0.5)
10343      */
10344     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10345     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10346     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10347     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10348     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10349     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10350     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10351     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10352     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10353     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10354     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10355     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10356     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10357     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10358
10359     hr = IDirect3DDevice9_BeginScene(device);
10360     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10361     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10362     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10363     hr = IDirect3DDevice9_EndScene(device);
10364     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10365
10366     color = getPixelColor(device, 320, 240);
10367     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10368        color);
10369     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10370     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10371
10372     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10373     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10374     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10375     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10376     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10377     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10378     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10379     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10380     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10381
10382     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10383      * stage 2: result = result + diffuse(1.0)
10384      */
10385     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10386     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10387     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10388     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10389     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10390     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10391     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10392     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10393     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10394     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10395     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10396     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10397     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10398     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10399
10400     hr = IDirect3DDevice9_BeginScene(device);
10401     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10402     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10403     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10404     hr = IDirect3DDevice9_EndScene(device);
10405     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10406
10407     color = getPixelColor(device, 320, 240);
10408     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10409        color);
10410     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10411     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10412
10413     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10414     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10415     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10416     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10417     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10418     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10419     IDirect3DTexture9_Release(texture);
10420 }
10421
10422 static void alphareplicate_test(IDirect3DDevice9 *device) {
10423     struct vertex quad[] = {
10424         { -1.0,    -1.0,    0.1,    0x80ff00ff },
10425         {  1.0,    -1.0,    0.1,    0x80ff00ff },
10426         { -1.0,     1.0,    0.1,    0x80ff00ff },
10427         {  1.0,     1.0,    0.1,    0x80ff00ff },
10428     };
10429     HRESULT hr;
10430     DWORD color;
10431
10432     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10433     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10434
10435     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10436     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10437
10438     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10439     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10440     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10441     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10442
10443     hr = IDirect3DDevice9_BeginScene(device);
10444     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10445     if(SUCCEEDED(hr)) {
10446         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10447         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10448         hr = IDirect3DDevice9_EndScene(device);
10449         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10450     }
10451
10452     color = getPixelColor(device, 320, 240);
10453     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10454        color);
10455     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10456     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10457
10458     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10459     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10460
10461 }
10462
10463 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10464     HRESULT hr;
10465     D3DCAPS9 caps;
10466     DWORD color;
10467     struct vertex quad[] = {
10468         { -1.0,    -1.0,    0.1,    0x408080c0 },
10469         {  1.0,    -1.0,    0.1,    0x408080c0 },
10470         { -1.0,     1.0,    0.1,    0x408080c0 },
10471         {  1.0,     1.0,    0.1,    0x408080c0 },
10472     };
10473
10474     memset(&caps, 0, sizeof(caps));
10475     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10476     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10477     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10478         skip("D3DTOP_DOTPRODUCT3 not supported\n");
10479         return;
10480     }
10481
10482     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10483     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10484
10485     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10486     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10487
10488     /* dp3_x4 r0, diffuse_bias, tfactor_bias
10489      * mov r0.a, diffuse.a
10490      * mov r0, r0.a
10491      *
10492      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10493      * 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
10494      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10495      */
10496     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10497     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10498     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10499     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10500     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10501     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10502     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10503     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10504     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10505     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10506     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10507     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10508     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10509     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10510     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10511     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10512     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10513     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10514
10515     hr = IDirect3DDevice9_BeginScene(device);
10516     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10517     if(SUCCEEDED(hr)) {
10518         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10519         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10520         hr = IDirect3DDevice9_EndScene(device);
10521         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10522     }
10523
10524     color = getPixelColor(device, 320, 240);
10525     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10526        color);
10527     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10528     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10529
10530     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10531     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10532     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10533     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10534     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10535     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10536 }
10537
10538 static void zwriteenable_test(IDirect3DDevice9 *device) {
10539     HRESULT hr;
10540     DWORD color;
10541     struct vertex quad1[] = {
10542         { -1.0,  -1.0,  0.1,    0x00ff0000},
10543         { -1.0,   1.0,  0.1,    0x00ff0000},
10544         {  1.0,  -1.0,  0.1,    0x00ff0000},
10545         {  1.0,   1.0,  0.1,    0x00ff0000},
10546     };
10547     struct vertex quad2[] = {
10548         { -1.0,  -1.0,  0.9,    0x0000ff00},
10549         { -1.0,   1.0,  0.9,    0x0000ff00},
10550         {  1.0,  -1.0,  0.9,    0x0000ff00},
10551         {  1.0,   1.0,  0.9,    0x0000ff00},
10552     };
10553
10554     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10555     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10556
10557     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10558     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10559     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10560     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10561     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10562     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10563     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10564     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10565
10566     hr = IDirect3DDevice9_BeginScene(device);
10567     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10568     if(SUCCEEDED(hr)) {
10569         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10570          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10571          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10572          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10573          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10574          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10575          */
10576         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10577         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10578         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10579         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10580         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10581         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10582
10583         hr = IDirect3DDevice9_EndScene(device);
10584         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10585     }
10586
10587     color = getPixelColor(device, 320, 240);
10588     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10589        color);
10590     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10591     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10592
10593     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10594     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10595 }
10596
10597 static void alphatest_test(IDirect3DDevice9 *device) {
10598 #define ALPHATEST_PASSED 0x0000ff00
10599 #define ALPHATEST_FAILED 0x00ff0000
10600     struct {
10601         D3DCMPFUNC  func;
10602         DWORD       color_less;
10603         DWORD       color_equal;
10604         DWORD       color_greater;
10605     } testdata[] = {
10606         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10607         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10608         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10609         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10610         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10611         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10612         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10613         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10614     };
10615     unsigned int i, j;
10616     HRESULT hr;
10617     DWORD color;
10618     struct vertex quad[] = {
10619         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10620         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10621         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10622         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10623     };
10624     D3DCAPS9 caps;
10625
10626     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10627     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10628     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10629     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10630
10631     for(j = 0; j < 2; j++) {
10632         if(j == 1) {
10633             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10634              * the alpha test either for performance reasons(floating point RTs) or to work
10635              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10636              * codepath for ffp and shader in this case, and the test should cover both
10637              */
10638             IDirect3DPixelShader9 *ps;
10639             DWORD shader_code[] = {
10640                 0xffff0101,                                 /* ps_1_1           */
10641                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10642                 0x0000ffff                                  /* end              */
10643             };
10644             memset(&caps, 0, sizeof(caps));
10645             hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10646             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10647             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10648                 break;
10649             }
10650
10651             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10652             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10653             hr = IDirect3DDevice9_SetPixelShader(device, ps);
10654             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10655             IDirect3DPixelShader9_Release(ps);
10656         }
10657
10658         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10659             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10660             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10661
10662             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10663             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10664             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10665             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10666             hr = IDirect3DDevice9_BeginScene(device);
10667             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10668             if(SUCCEEDED(hr)) {
10669                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10670                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10671                 hr = IDirect3DDevice9_EndScene(device);
10672                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10673             }
10674             color = getPixelColor(device, 320, 240);
10675             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10676             color, testdata[i].color_less, testdata[i].func);
10677             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10678             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10679
10680             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10681             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10682             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10683             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10684             hr = IDirect3DDevice9_BeginScene(device);
10685             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10686             if(SUCCEEDED(hr)) {
10687                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10688                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10689                 hr = IDirect3DDevice9_EndScene(device);
10690                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10691             }
10692             color = getPixelColor(device, 320, 240);
10693             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10694             color, testdata[i].color_equal, testdata[i].func);
10695             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10696             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10697
10698             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10699             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10700             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10701             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10702             hr = IDirect3DDevice9_BeginScene(device);
10703             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10704             if(SUCCEEDED(hr)) {
10705                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10706                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10707                 hr = IDirect3DDevice9_EndScene(device);
10708                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10709             }
10710             color = getPixelColor(device, 320, 240);
10711             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10712             color, testdata[i].color_greater, testdata[i].func);
10713             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10714             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10715         }
10716     }
10717
10718     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10719     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10720     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10721     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10722 }
10723
10724 static void sincos_test(IDirect3DDevice9 *device) {
10725     const DWORD sin_shader_code[] = {
10726         0xfffe0200,                                                                 /* vs_2_0                       */
10727         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10728         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10729         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10730         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10731         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10732         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10733         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10734         0x0000ffff                                                                  /* end                          */
10735     };
10736     const DWORD cos_shader_code[] = {
10737         0xfffe0200,                                                                 /* vs_2_0                       */
10738         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10739         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10740         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10741         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10742         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10743         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10744         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10745         0x0000ffff                                                                  /* end                          */
10746     };
10747     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10748     HRESULT hr;
10749     struct {
10750         float x, y, z;
10751     } data[1280];
10752     unsigned int i;
10753     float sincosc1[4] = {D3DSINCOSCONST1};
10754     float sincosc2[4] = {D3DSINCOSCONST2};
10755
10756     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10757     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10758
10759     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10760     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10761     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10762     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10763     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10764     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10765     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10766     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10767     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10768     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10769
10770     /* Generate a point from -1 to 1 every 0.5 pixels */
10771     for(i = 0; i < 1280; i++) {
10772         data[i].x = (-640.0 + i) / 640.0;
10773         data[i].y = 0.0;
10774         data[i].z = 0.1;
10775     }
10776
10777     hr = IDirect3DDevice9_BeginScene(device);
10778     if(SUCCEEDED(hr)) {
10779         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10780         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10781         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10782         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10783
10784         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10785         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10786         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10787         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10788
10789         hr = IDirect3DDevice9_EndScene(device);
10790         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10791     }
10792     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10793     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10794     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10795
10796     IDirect3DDevice9_SetVertexShader(device, NULL);
10797     IDirect3DVertexShader9_Release(sin_shader);
10798     IDirect3DVertexShader9_Release(cos_shader);
10799 }
10800
10801 static void loop_index_test(IDirect3DDevice9 *device) {
10802     const DWORD shader_code[] = {
10803         0xfffe0200,                                                 /* vs_2_0                   */
10804         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10805         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10806         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10807         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10808         0x0000001d,                                                 /* endloop                  */
10809         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10810         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10811         0x0000ffff                                                  /* END                      */
10812     };
10813     IDirect3DVertexShader9 *shader;
10814     HRESULT hr;
10815     DWORD color;
10816     const float quad[] = {
10817         -1.0,   -1.0,   0.1,
10818          1.0,   -1.0,   0.1,
10819         -1.0,    1.0,   0.1,
10820          1.0,    1.0,   0.1
10821     };
10822     const float zero[4] = {0, 0, 0, 0};
10823     const float one[4] = {1, 1, 1, 1};
10824     int i0[4] = {2, 10, -3, 0};
10825     float values[4];
10826
10827     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10828     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10829     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10830     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10831     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10832     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10833     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10834     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10835
10836     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10837     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10838     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10839     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10840     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10841     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10842     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10843     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10844     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10845     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10846     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10847     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10848     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10849     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10850     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10851     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10852     values[0] = 1.0;
10853     values[1] = 1.0;
10854     values[2] = 0.0;
10855     values[3] = 0.0;
10856     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10857     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10858     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10859     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10860     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10861     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10862     values[0] = -1.0;
10863     values[1] = 0.0;
10864     values[2] = 0.0;
10865     values[3] = 0.0;
10866     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10867     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10868     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10869     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10870     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10871     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10872     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10873     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10874     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10875     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10876
10877     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10878     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10879
10880     hr = IDirect3DDevice9_BeginScene(device);
10881     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10882     if(SUCCEEDED(hr))
10883     {
10884         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10885         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10886         hr = IDirect3DDevice9_EndScene(device);
10887         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10888     }
10889     color = getPixelColor(device, 320, 240);
10890     ok(color_match(color, 0x0000ff00, 1),
10891        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10892     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10893     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10894
10895     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10896     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10897     IDirect3DVertexShader9_Release(shader);
10898 }
10899
10900 static void sgn_test(IDirect3DDevice9 *device) {
10901     const DWORD shader_code[] = {
10902         0xfffe0200,                                                             /* vs_2_0                       */
10903         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10904         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10905         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10906         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10907         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10908         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10909         0x0000ffff                                                              /* end                          */
10910     };
10911     IDirect3DVertexShader9 *shader;
10912     HRESULT hr;
10913     DWORD color;
10914     const float quad[] = {
10915         -1.0,   -1.0,   0.1,
10916          1.0,   -1.0,   0.1,
10917         -1.0,    1.0,   0.1,
10918          1.0,    1.0,   0.1
10919     };
10920
10921     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10922     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10923     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10924     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10925     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10926     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10927     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10928     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10929
10930     hr = IDirect3DDevice9_BeginScene(device);
10931     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10932     if(SUCCEEDED(hr))
10933     {
10934         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10935         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10936         hr = IDirect3DDevice9_EndScene(device);
10937         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10938     }
10939     color = getPixelColor(device, 320, 240);
10940     ok(color_match(color, 0x008000ff, 1),
10941        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10942     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10943     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10944
10945     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10946     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10947     IDirect3DVertexShader9_Release(shader);
10948 }
10949
10950 static void viewport_test(IDirect3DDevice9 *device) {
10951     HRESULT hr;
10952     DWORD color;
10953     D3DVIEWPORT9 vp, old_vp;
10954     BOOL draw_failed = TRUE;
10955     const float quad[] =
10956     {
10957         -0.5,   -0.5,   0.1,
10958          0.5,   -0.5,   0.1,
10959         -0.5,    0.5,   0.1,
10960          0.5,    0.5,   0.1
10961     };
10962
10963     memset(&old_vp, 0, sizeof(old_vp));
10964     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10965     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10966
10967     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10968     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10969
10970     /* Test a viewport with Width and Height bigger than the surface dimensions
10971      *
10972      * TODO: Test Width < surface.width, but X + Width > surface.width
10973      * TODO: Test Width < surface.width, what happens with the height?
10974      *
10975      * The expected behavior is that the viewport behaves like the "default"
10976      * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
10977      * MinZ = 0.0, MaxZ = 1.0.
10978      *
10979      * Starting with Windows 7 the behavior among driver versions is not
10980      * consistent. The SetViewport call is accepted on all drivers. Some
10981      * drivers(older nvidia ones) refuse to draw and return an error. Newer
10982      * nvidia drivers draw, but use the actual values in the viewport and only
10983      * display the upper left part on the surface.
10984      */
10985     memset(&vp, 0, sizeof(vp));
10986     vp.X = 0;
10987     vp.Y = 0;
10988     vp.Width = 10000;
10989     vp.Height = 10000;
10990     vp.MinZ = 0.0;
10991     vp.MaxZ = 0.0;
10992     hr = IDirect3DDevice9_SetViewport(device, &vp);
10993     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10994
10995     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10996     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10997     hr = IDirect3DDevice9_BeginScene(device);
10998     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10999     if(SUCCEEDED(hr))
11000     {
11001         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11002         ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
11003         draw_failed = FAILED(hr);
11004         hr = IDirect3DDevice9_EndScene(device);
11005         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
11006     }
11007
11008     if(!draw_failed)
11009     {
11010         color = getPixelColor(device, 158, 118);
11011         ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
11012         color = getPixelColor(device, 162, 118);
11013         ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
11014         color = getPixelColor(device, 158, 122);
11015         ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
11016         color = getPixelColor(device, 162, 122);
11017         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
11018
11019         color = getPixelColor(device, 478, 358);
11020         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
11021         color = getPixelColor(device, 482, 358);
11022         ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
11023         color = getPixelColor(device, 478, 362);
11024         ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
11025         color = getPixelColor(device, 482, 362);
11026         ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
11027     }
11028
11029     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11030     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
11031
11032     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
11033     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
11034 }
11035
11036 /* This test tests depth clamping / clipping behaviour:
11037  *   - With software vertex processing, depth values are clamped to the
11038  *     minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
11039  *     when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
11040  *     same as regular vertices here.
11041  *   - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
11042  *     Normal vertices are always clipped. Pretransformed vertices are
11043  *     clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
11044  *   - The viewport's MinZ/MaxZ is irrelevant for this.
11045  */
11046 static void depth_clamp_test(IDirect3DDevice9 *device)
11047 {
11048     const struct tvertex quad1[] =
11049     {
11050         {  0.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
11051         {640.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
11052         {  0.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
11053         {640.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
11054     };
11055     const struct tvertex quad2[] =
11056     {
11057         {  0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
11058         {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
11059         {  0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
11060         {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
11061     };
11062     const struct tvertex quad3[] =
11063     {
11064         {112.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
11065         {208.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
11066         {112.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
11067         {208.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
11068     };
11069     const struct tvertex quad4[] =
11070     {
11071         { 42.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
11072         {112.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
11073         { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
11074         {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
11075     };
11076     const struct vertex quad5[] =
11077     {
11078         { -0.5f,   0.5f, 10.0f,       0xff14f914},
11079         {  0.5f,   0.5f, 10.0f,       0xff14f914},
11080         { -0.5f,  -0.5f, 10.0f,       0xff14f914},
11081         {  0.5f,  -0.5f, 10.0f,       0xff14f914},
11082     };
11083     const struct vertex quad6[] =
11084     {
11085         { -1.0f,   0.5f, 10.0f,      0xfff91414},
11086         {  1.0f,   0.5f, 10.0f,      0xfff91414},
11087         { -1.0f,  0.25f, 10.0f,      0xfff91414},
11088         {  1.0f,  0.25f, 10.0f,      0xfff91414},
11089     };
11090
11091     D3DVIEWPORT9 vp;
11092     D3DCOLOR color;
11093     D3DCAPS9 caps;
11094     HRESULT hr;
11095
11096     vp.X = 0;
11097     vp.Y = 0;
11098     vp.Width = 640;
11099     vp.Height = 480;
11100     vp.MinZ = 0.0;
11101     vp.MaxZ = 7.5;
11102
11103     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11104     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11105
11106     hr = IDirect3DDevice9_SetViewport(device, &vp);
11107     if(FAILED(hr))
11108     {
11109         /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
11110          * the tests because the 7.5 is just intended to show that it doesn't have
11111          * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
11112          * viewport and continue.
11113          */
11114         ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
11115         vp.MaxZ = 1.0;
11116         hr = IDirect3DDevice9_SetViewport(device, &vp);
11117     }
11118     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11119
11120     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
11121     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11122
11123     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
11124     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11125     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11126     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11127     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11128     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11129     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11130     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11131
11132     hr = IDirect3DDevice9_BeginScene(device);
11133     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11134
11135     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11136     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11137
11138     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11139     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11140     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11141     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11142
11143     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11144     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11145
11146     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11147     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11148     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
11149     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11150
11151     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
11152     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11153
11154     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11155     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11156
11157     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
11158     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11159
11160     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11161     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11162
11163     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
11164     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11165
11166     hr = IDirect3DDevice9_EndScene(device);
11167     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11168
11169     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
11170     {
11171         color = getPixelColor(device, 75, 75);
11172         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11173         color = getPixelColor(device, 150, 150);
11174         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11175         color = getPixelColor(device, 320, 240);
11176         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11177         color = getPixelColor(device, 320, 330);
11178         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11179         color = getPixelColor(device, 320, 330);
11180         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11181     }
11182     else
11183     {
11184         color = getPixelColor(device, 75, 75);
11185         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11186         color = getPixelColor(device, 150, 150);
11187         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11188         color = getPixelColor(device, 320, 240);
11189         ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11190         color = getPixelColor(device, 320, 330);
11191         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11192         color = getPixelColor(device, 320, 330);
11193         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11194     }
11195
11196     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11197     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11198
11199     vp.MinZ = 0.0;
11200     vp.MaxZ = 1.0;
11201     hr = IDirect3DDevice9_SetViewport(device, &vp);
11202     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11203 }
11204
11205 static void depth_bounds_test(IDirect3DDevice9 *device)
11206 {
11207     const struct tvertex quad1[] =
11208     {
11209         {    0,    0, 0.0f, 1, 0xfff9e814},
11210         {  640,    0, 0.0f, 1, 0xfff9e814},
11211         {    0,  480, 1.0f, 1, 0xfff9e814},
11212         {  640,  480, 1.0f, 1, 0xfff9e814},
11213     };
11214     const struct tvertex quad2[] =
11215     {
11216         {    0,    0,  0.6f, 1, 0xff002b7f},
11217         {  640,    0,  0.6f, 1, 0xff002b7f},
11218         {    0,  480,  0.6f, 1, 0xff002b7f},
11219         {  640,  480,  0.6f, 1, 0xff002b7f},
11220     };
11221     const struct tvertex quad3[] =
11222     {
11223         {    0,  100, 0.6f, 1, 0xfff91414},
11224         {  640,  100, 0.6f, 1, 0xfff91414},
11225         {    0,  160, 0.6f, 1, 0xfff91414},
11226         {  640,  160, 0.6f, 1, 0xfff91414},
11227     };
11228
11229     union {
11230         DWORD d;
11231         float f;
11232     } tmpvalue;
11233
11234     IDirect3D9 *d3d = NULL;
11235     IDirect3DSurface9 *offscreen_surface = NULL;
11236     D3DCOLOR color;
11237     HRESULT hr;
11238
11239     IDirect3DDevice9_GetDirect3D(device, &d3d);
11240     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11241             0,  D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
11242         skip("No NVDB (depth bounds test) support\n");
11243         IDirect3D9_Release(d3d);
11244         return;
11245     }
11246     IDirect3D9_Release(d3d);
11247
11248     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
11249             MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
11250     ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
11251     if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
11252
11253     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
11254     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11255
11256     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11257     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11258     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
11259     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11260     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11261     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11262     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11263     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11264
11265
11266     hr = IDirect3DDevice9_BeginScene(device);
11267     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11268
11269     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11270     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11271
11272     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11273     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11274
11275     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
11276     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11277
11278     tmpvalue.f = 0.625;
11279     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11280     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11281
11282     tmpvalue.f = 0.75;
11283     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
11284     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11285
11286     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11287     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11288
11289     tmpvalue.f = 0.75;
11290     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11291     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11292
11293     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11294     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11295
11296     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
11297     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11298
11299     hr = IDirect3DDevice9_EndScene(device);
11300     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11301
11302     color = getPixelColor(device, 150, 130);
11303     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11304     color = getPixelColor(device, 150, 200);
11305     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11306     color = getPixelColor(device, 150, 300-5);
11307     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11308     color = getPixelColor(device, 150, 300+5);
11309     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11310     color = getPixelColor(device, 150, 330);
11311     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11312     color = getPixelColor(device, 150, 360-5);
11313     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11314     color = getPixelColor(device, 150, 360+5);
11315     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11316
11317     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11318     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11319 }
11320
11321 static void depth_buffer_test(IDirect3DDevice9 *device)
11322 {
11323     static const struct vertex quad1[] =
11324     {
11325         { -1.0,  1.0, 0.33f, 0xff00ff00},
11326         {  1.0,  1.0, 0.33f, 0xff00ff00},
11327         { -1.0, -1.0, 0.33f, 0xff00ff00},
11328         {  1.0, -1.0, 0.33f, 0xff00ff00},
11329     };
11330     static const struct vertex quad2[] =
11331     {
11332         { -1.0,  1.0, 0.50f, 0xffff00ff},
11333         {  1.0,  1.0, 0.50f, 0xffff00ff},
11334         { -1.0, -1.0, 0.50f, 0xffff00ff},
11335         {  1.0, -1.0, 0.50f, 0xffff00ff},
11336     };
11337     static const struct vertex quad3[] =
11338     {
11339         { -1.0,  1.0, 0.66f, 0xffff0000},
11340         {  1.0,  1.0, 0.66f, 0xffff0000},
11341         { -1.0, -1.0, 0.66f, 0xffff0000},
11342         {  1.0, -1.0, 0.66f, 0xffff0000},
11343     };
11344     static const DWORD expected_colors[4][4] =
11345     {
11346         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11347         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11348         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11349         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11350     };
11351
11352     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
11353     unsigned int i, j;
11354     D3DVIEWPORT9 vp;
11355     D3DCOLOR color;
11356     HRESULT hr;
11357
11358     vp.X = 0;
11359     vp.Y = 0;
11360     vp.Width = 640;
11361     vp.Height = 480;
11362     vp.MinZ = 0.0;
11363     vp.MaxZ = 1.0;
11364
11365     hr = IDirect3DDevice9_SetViewport(device, &vp);
11366     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11367
11368     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11369     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11370     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11371     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11372     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11373     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11374     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11375     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11376     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11377     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11378
11379     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11380     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11381     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
11382             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11383     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11384     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11385             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11386     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11387     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11388             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
11389     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11390
11391     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11392     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11393     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11394     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11395
11396     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11397     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11398     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11399     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11400
11401     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11402     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11403     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11404     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11405
11406     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11407     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11408     hr = IDirect3DDevice9_BeginScene(device);
11409     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11410     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11411     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11412     hr = IDirect3DDevice9_EndScene(device);
11413     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11414
11415     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11416     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11417
11418     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11419     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11420
11421     hr = IDirect3DDevice9_BeginScene(device);
11422     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11423     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11424     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11425     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11426     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11427     hr = IDirect3DDevice9_EndScene(device);
11428     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11429
11430     for (i = 0; i < 4; ++i)
11431     {
11432         for (j = 0; j < 4; ++j)
11433         {
11434             unsigned int x = 80 * ((2 * j) + 1);
11435             unsigned int y = 60 * ((2 * i) + 1);
11436             color = getPixelColor(device, x, y);
11437             ok(color_match(color, expected_colors[i][j], 0),
11438                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11439         }
11440     }
11441
11442     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11443     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11444
11445     IDirect3DSurface9_Release(backbuffer);
11446     IDirect3DSurface9_Release(rt3);
11447     IDirect3DSurface9_Release(rt2);
11448     IDirect3DSurface9_Release(rt1);
11449 }
11450
11451 /* Test that partial depth copies work the way they're supposed to. The clear
11452  * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
11453  * the following draw should only copy back the part that was modified. */
11454 static void depth_buffer2_test(IDirect3DDevice9 *device)
11455 {
11456     static const struct vertex quad[] =
11457     {
11458         { -1.0,  1.0, 0.66f, 0xffff0000},
11459         {  1.0,  1.0, 0.66f, 0xffff0000},
11460         { -1.0, -1.0, 0.66f, 0xffff0000},
11461         {  1.0, -1.0, 0.66f, 0xffff0000},
11462     };
11463
11464     IDirect3DSurface9 *backbuffer, *rt1, *rt2;
11465     unsigned int i, j;
11466     D3DVIEWPORT9 vp;
11467     D3DCOLOR color;
11468     HRESULT hr;
11469
11470     vp.X = 0;
11471     vp.Y = 0;
11472     vp.Width = 640;
11473     vp.Height = 480;
11474     vp.MinZ = 0.0;
11475     vp.MaxZ = 1.0;
11476
11477     hr = IDirect3DDevice9_SetViewport(device, &vp);
11478     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11479
11480     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11481     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11482     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11483     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11484     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11485     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11486     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11487     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11488     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11489     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11490
11491     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11492             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11493     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11494     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11495             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11496     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11497     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11498     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11499
11500     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11501     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11502     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11503     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11504
11505     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11506     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11507     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
11508     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11509
11510     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11511     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11512     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11513     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11514
11515     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11516     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11517
11518     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11519     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11520
11521     hr = IDirect3DDevice9_BeginScene(device);
11522     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11523     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11524     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11525     hr = IDirect3DDevice9_EndScene(device);
11526     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11527
11528     for (i = 0; i < 4; ++i)
11529     {
11530         for (j = 0; j < 4; ++j)
11531         {
11532             unsigned int x = 80 * ((2 * j) + 1);
11533             unsigned int y = 60 * ((2 * i) + 1);
11534             color = getPixelColor(device, x, y);
11535             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11536                     "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
11537         }
11538     }
11539
11540     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11541     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11542
11543     IDirect3DSurface9_Release(backbuffer);
11544     IDirect3DSurface9_Release(rt2);
11545     IDirect3DSurface9_Release(rt1);
11546 }
11547
11548 static void depth_blit_test(IDirect3DDevice9 *device)
11549 {
11550     static const struct vertex quad1[] =
11551     {
11552         { -1.0,  1.0, 0.33f, 0xff00ff00},
11553         {  1.0,  1.0, 0.33f, 0xff00ff00},
11554         { -1.0, -1.0, 0.33f, 0xff00ff00},
11555         {  1.0, -1.0, 0.33f, 0xff00ff00},
11556     };
11557     static const struct vertex quad2[] =
11558     {
11559         { -1.0,  1.0, 0.66f, 0xff0000ff},
11560         {  1.0,  1.0, 0.66f, 0xff0000ff},
11561         { -1.0, -1.0, 0.66f, 0xff0000ff},
11562         {  1.0, -1.0, 0.66f, 0xff0000ff},
11563     };
11564     static const DWORD expected_colors[4][4] =
11565     {
11566         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11567         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11568         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11569         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11570     };
11571
11572     IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
11573     RECT src_rect, dst_rect;
11574     unsigned int i, j;
11575     D3DVIEWPORT9 vp;
11576     D3DCOLOR color;
11577     HRESULT hr;
11578
11579     vp.X = 0;
11580     vp.Y = 0;
11581     vp.Width = 640;
11582     vp.Height = 480;
11583     vp.MinZ = 0.0;
11584     vp.MaxZ = 1.0;
11585
11586     hr = IDirect3DDevice9_SetViewport(device, &vp);
11587     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11588
11589     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11590     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11591     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11592     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11593     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11594     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11595     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11596     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11597     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
11598     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11599
11600     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11601     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11602     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11603     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11604     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11605     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11606     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11607     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11608
11609     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11610     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11611     SetRect(&dst_rect, 0, 0, 480, 360);
11612     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11613     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11614     SetRect(&dst_rect, 0, 0, 320, 240);
11615     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11616     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11617
11618     /* Partial blit. */
11619     SetRect(&src_rect, 0, 0, 320, 240);
11620     SetRect(&dst_rect, 0, 0, 320, 240);
11621     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11622     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11623     /* Flipped. */
11624     SetRect(&src_rect, 0, 0, 640, 480);
11625     SetRect(&dst_rect, 0, 480, 640, 0);
11626     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11627     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11628     /* Full, explicit. */
11629     SetRect(&src_rect, 0, 0, 640, 480);
11630     SetRect(&dst_rect, 0, 0, 640, 480);
11631     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11632     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11633     /* Filtered blit. */
11634     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11635     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11636     /* Depth -> color blit.*/
11637     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11638     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11639     IDirect3DSurface9_Release(backbuffer);
11640     /* Full surface, different sizes */
11641     hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
11642     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11643     hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
11644     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11645
11646     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11647     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11648     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11649     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11650     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11651     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11652
11653     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11654     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11655     hr = IDirect3DDevice9_BeginScene(device);
11656     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11657     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11658     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11659     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11660     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11661     hr = IDirect3DDevice9_EndScene(device);
11662     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11663
11664     for (i = 0; i < 4; ++i)
11665     {
11666         for (j = 0; j < 4; ++j)
11667         {
11668             unsigned int x = 80 * ((2 * j) + 1);
11669             unsigned int y = 60 * ((2 * i) + 1);
11670             color = getPixelColor(device, x, y);
11671             ok(color_match(color, expected_colors[i][j], 0),
11672                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11673         }
11674     }
11675
11676     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11677     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11678
11679     IDirect3DSurface9_Release(ds3);
11680     IDirect3DSurface9_Release(ds2);
11681     IDirect3DSurface9_Release(ds1);
11682 }
11683
11684 static void intz_test(IDirect3DDevice9 *device)
11685 {
11686     static const DWORD ps_code[] =
11687     {
11688         0xffff0200,                                                             /* ps_2_0                       */
11689         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11690         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11691         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11692         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11693         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11694         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11695         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11696         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11697         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
11698         0x0000ffff,                                                             /* end                          */
11699     };
11700     struct
11701     {
11702         float x, y, z;
11703         float s, t, p, q;
11704     }
11705     quad[] =
11706     {
11707         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11708         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11709         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11710         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11711     },
11712     half_quad_1[] =
11713     {
11714         { -1.0f,  0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11715         {  1.0f,  0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11716         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11717         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11718     },
11719     half_quad_2[] =
11720     {
11721         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11722         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11723         { -1.0f,  0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11724         {  1.0f,  0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11725     };
11726     struct
11727     {
11728         UINT x, y;
11729         D3DCOLOR color;
11730     }
11731     expected_colors[] =
11732     {
11733         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11734         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11735         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11736         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11737         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11738         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11739         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11740         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11741     };
11742
11743     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11744     IDirect3DTexture9 *texture;
11745     IDirect3DPixelShader9 *ps;
11746     IDirect3DSurface9 *ds;
11747     IDirect3D9 *d3d9;
11748     D3DCAPS9 caps;
11749     HRESULT hr;
11750     UINT i;
11751
11752     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11753     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11754     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11755     {
11756         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11757         return;
11758     }
11759     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
11760     {
11761         skip("No unconditional NP2 texture support, skipping INTZ test.\n");
11762         return;
11763     }
11764
11765     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11766     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11767
11768     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11769             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11770     if (FAILED(hr))
11771     {
11772         skip("No INTZ support, skipping INTZ test.\n");
11773         return;
11774     }
11775
11776     IDirect3D9_Release(d3d9);
11777
11778     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11779     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11780     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11781     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11782
11783     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11784             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11785     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11786     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11787             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11788     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11789     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11790     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11791
11792     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11793     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11794     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11795     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11796     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11797     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11798     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11799     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11800     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11801     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11802
11803     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11804     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11805     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11806     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11807     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11808     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11809     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11810     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11811     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11812     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11813
11814     /* Render offscreen, using the INTZ texture as depth buffer */
11815     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11816     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11817     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11818     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11819     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11820     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11821     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11822     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11823
11824     /* Setup the depth/stencil surface. */
11825     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11826     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11827
11828     hr = IDirect3DDevice9_BeginScene(device);
11829     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11830     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11831     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11832     hr = IDirect3DDevice9_EndScene(device);
11833     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11834
11835     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11836     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11837     IDirect3DSurface9_Release(ds);
11838     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11839     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11840     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11841     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11842     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11843     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11844
11845     /* Read the depth values back. */
11846     hr = IDirect3DDevice9_BeginScene(device);
11847     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11848     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11849     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11850     hr = IDirect3DDevice9_EndScene(device);
11851     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11852
11853     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11854     {
11855         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11856         ok(color_match(color, expected_colors[i].color, 1),
11857                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11858                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11859     }
11860
11861     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11862     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11863
11864     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11865     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11866     IDirect3DTexture9_Release(texture);
11867
11868     /* Render onscreen while using the INTZ texture as depth buffer */
11869     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11870             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11871     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11872     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11873     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11874     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11875     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11876     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11877
11878     /* Setup the depth/stencil surface. */
11879     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11880     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11881
11882     hr = IDirect3DDevice9_BeginScene(device);
11883     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11884     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11885     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11886     hr = IDirect3DDevice9_EndScene(device);
11887     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11888
11889     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11890     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11891     IDirect3DSurface9_Release(ds);
11892     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11893     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11894     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11895     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11896
11897     /* Read the depth values back. */
11898     hr = IDirect3DDevice9_BeginScene(device);
11899     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11900     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11901     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11902     hr = IDirect3DDevice9_EndScene(device);
11903     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11904
11905     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11906     {
11907         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11908         ok(color_match(color, expected_colors[i].color, 1),
11909                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11910                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11911     }
11912
11913     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11914     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11915
11916     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11917     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11918     IDirect3DTexture9_Release(texture);
11919
11920     /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
11921     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11922             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11923     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11924     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11925
11926     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11927     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11928     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11929     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11930     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11931     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11932
11933     /* Setup the depth/stencil surface. */
11934     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11935     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11936
11937     hr = IDirect3DDevice9_BeginScene(device);
11938     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11939     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
11940     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11941     hr = IDirect3DDevice9_EndScene(device);
11942     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11943
11944     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11945     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11946
11947     hr = IDirect3DDevice9_BeginScene(device);
11948     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11949     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
11950     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11951     hr = IDirect3DDevice9_EndScene(device);
11952     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11953
11954     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11955     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11956     IDirect3DSurface9_Release(ds);
11957     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11958     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11959     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11960     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11961
11962     /* Read the depth values back. */
11963     hr = IDirect3DDevice9_BeginScene(device);
11964     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11965     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11966     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11967     hr = IDirect3DDevice9_EndScene(device);
11968     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11969
11970     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11971     {
11972         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11973         ok(color_match(color, expected_colors[i].color, 1),
11974                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11975                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11976     }
11977
11978     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11979     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11980
11981     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11982     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11983     IDirect3DSurface9_Release(original_ds);
11984     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11985     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11986     IDirect3DTexture9_Release(texture);
11987     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11988     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11989     IDirect3DPixelShader9_Release(ps);
11990
11991     IDirect3DSurface9_Release(original_rt);
11992     IDirect3DSurface9_Release(rt);
11993 }
11994
11995 static void shadow_test(IDirect3DDevice9 *device)
11996 {
11997     static const DWORD ps_code[] =
11998     {
11999         0xffff0200,                                                             /* ps_2_0                       */
12000         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
12001         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
12002         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
12003         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
12004         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
12005         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
12006         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
12007         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
12008         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
12009         0x0000ffff,                                                             /* end                          */
12010     };
12011     struct
12012     {
12013         D3DFORMAT format;
12014         const char *name;
12015     }
12016     formats[] =
12017     {
12018         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
12019         {D3DFMT_D32,            "D3DFMT_D32"},
12020         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
12021         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
12022         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
12023         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
12024         {D3DFMT_D16,            "D3DFMT_D16"},
12025         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
12026         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
12027     };
12028     struct
12029     {
12030         float x, y, z;
12031         float s, t, p, q;
12032     }
12033     quad[] =
12034     {
12035         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
12036         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
12037         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
12038         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
12039     };
12040     struct
12041     {
12042         UINT x, y;
12043         D3DCOLOR color;
12044     }
12045     expected_colors[] =
12046     {
12047         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12048         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12049         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12050         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12051         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12052         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12053         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12054         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12055     };
12056
12057     IDirect3DSurface9 *original_ds, *original_rt, *rt;
12058     IDirect3DPixelShader9 *ps;
12059     IDirect3D9 *d3d9;
12060     D3DCAPS9 caps;
12061     HRESULT hr;
12062     UINT i;
12063
12064     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12065     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12066     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
12067     {
12068         skip("No pixel shader 2.0 support, skipping shadow test.\n");
12069         return;
12070     }
12071
12072     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
12073     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12074     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12075     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12076     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
12077     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
12078
12079     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
12080             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12081     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12082     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12083     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12084
12085     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
12086     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12087     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12088     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12089     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
12090     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12091     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12092     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12093     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12094     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12095
12096     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
12097     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12098     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
12099     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12100     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
12101     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12102     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
12103     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12104     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12105     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12106
12107     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
12108     {
12109         D3DFORMAT format = formats[i].format;
12110         IDirect3DTexture9 *texture;
12111         IDirect3DSurface9 *ds;
12112         unsigned int j;
12113
12114         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12115                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
12116         if (FAILED(hr)) continue;
12117
12118         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
12119                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
12120         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12121
12122         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
12123         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12124
12125         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12126         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12127
12128         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12129         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12130
12131         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12132         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12133
12134         /* Setup the depth/stencil surface. */
12135         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
12136         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12137
12138         hr = IDirect3DDevice9_BeginScene(device);
12139         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12140         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12141         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12142         hr = IDirect3DDevice9_EndScene(device);
12143         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12144
12145         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
12146         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12147         IDirect3DSurface9_Release(ds);
12148
12149         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12150         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12151
12152         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12153         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12154
12155         hr = IDirect3DDevice9_SetPixelShader(device, ps);
12156         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12157
12158         /* Do the actual shadow mapping. */
12159         hr = IDirect3DDevice9_BeginScene(device);
12160         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12161         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12162         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12163         hr = IDirect3DDevice9_EndScene(device);
12164         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12165
12166         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12167         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12168         IDirect3DTexture9_Release(texture);
12169
12170         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
12171         {
12172             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
12173             ok(color_match(color, expected_colors[j].color, 0),
12174                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
12175                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
12176                     formats[i].name, color);
12177         }
12178
12179         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12180         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12181     }
12182
12183     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12184     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12185     IDirect3DPixelShader9_Release(ps);
12186
12187     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
12188     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12189     IDirect3DSurface9_Release(original_ds);
12190
12191     IDirect3DSurface9_Release(original_rt);
12192     IDirect3DSurface9_Release(rt);
12193
12194     IDirect3D9_Release(d3d9);
12195 }
12196
12197 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
12198 {
12199     const struct vertex quad1[] =
12200     {
12201         {-1.0f, -1.0f, 0.0f, 0xfff9e814},
12202         { 1.0f, -1.0f, 0.0f, 0xfff9e814},
12203         {-1.0f,  1.0f, 0.0f, 0xfff9e814},
12204         { 1.0f,  1.0f, 0.0f, 0xfff9e814},
12205     };
12206     const struct vertex quad2[] =
12207     {
12208         {-1.0f, -1.0f, 0.0f, 0xff002b7f},
12209         { 1.0f, -1.0f, 0.0f, 0xff002b7f},
12210         {-1.0f,  1.0f, 0.0f, 0xff002b7f},
12211         { 1.0f,  1.0f, 0.0f, 0xff002b7f},
12212     };
12213     D3DCOLOR color;
12214     HRESULT hr;
12215
12216     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
12217     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12218
12219     hr = IDirect3DDevice9_BeginScene(device);
12220     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12221
12222     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12223     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12224
12225     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12226     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12227     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12228     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12229
12230     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
12231     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12232     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12233     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12234
12235     hr = IDirect3DDevice9_EndScene(device);
12236     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12237
12238     color = getPixelColor(device, 1, 240);
12239     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12240     color = getPixelColor(device, 638, 240);
12241     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12242
12243     color = getPixelColor(device, 1, 241);
12244     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12245     color = getPixelColor(device, 638, 241);
12246     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12247 }
12248
12249 static void clip_planes_test(IDirect3DDevice9 *device)
12250 {
12251     const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
12252
12253     const DWORD shader_code[] = {
12254         0xfffe0200, /* vs_2_0 */
12255         0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12256         0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
12257         0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12258         0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
12259         0x0000ffff /* end */
12260     };
12261     IDirect3DVertexShader9 *shader;
12262
12263     IDirect3DTexture9 *offscreen = NULL;
12264     IDirect3DSurface9 *offscreen_surface, *original_rt;
12265     HRESULT hr;
12266
12267     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12268     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12269
12270     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12271     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12272     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12273     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12274     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12275     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12276     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
12277     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12278
12279     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12280     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12281     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12282     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
12283
12284     IDirect3DDevice9_SetClipPlane(device, 0, plane0);
12285
12286     clip_planes(device, "Onscreen FFP");
12287
12288     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
12289     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12290     hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
12291     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12292     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12293     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12294
12295     clip_planes(device, "Offscreen FFP");
12296
12297     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12298     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12299
12300     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12301     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
12302     hr = IDirect3DDevice9_SetVertexShader(device, shader);
12303     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
12304
12305     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12306     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12307
12308     clip_planes(device, "Onscreen vertex shader");
12309
12310     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12311     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12312
12313     clip_planes(device, "Offscreen vertex shader");
12314
12315     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12316     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12317
12318     IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12319     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12320     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12321     IDirect3DVertexShader9_Release(shader);
12322     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12323     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12324     IDirect3DSurface9_Release(original_rt);
12325     IDirect3DSurface9_Release(offscreen_surface);
12326     IDirect3DTexture9_Release(offscreen);
12327 }
12328
12329 static void fp_special_test(IDirect3DDevice9 *device)
12330 {
12331     /* Microsoft's assembler generates nan and inf with "1.#QNAN" and "1.#INF." respectively */
12332     static const DWORD vs_header[] =
12333     {
12334         0xfffe0200,                                                             /* vs_2_0                       */
12335         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
12336         0x05000051, 0xa00f0001, 0x7fc00000, 0xff800000, 0x7f800000, 0x00000000, /* def c1, nan, -inf, inf, 0    */
12337         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
12338         0x0200001f, 0x80000005, 0x900f0001,                                     /* dcl_texcoord0 v1             */
12339     };
12340
12341     static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001};         /* log r0.x, v1.x               */
12342     static const DWORD vs_pow[] =
12343             {0x03000020, 0x80010000, 0x90000001, 0x90000001};                   /* pow r0.x, v1.x, v1.x         */
12344     static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001};         /* nrm r0.xyz, v1.x             */
12345     static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001};        /* rcp r0.x, v1.x               */
12346     static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001};        /* rcp r0.x, -v1.x              */
12347     static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001};        /* rsq r0.x, v1.x               */
12348     static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001};        /* rsq r0.x, -v1.x              */
12349     static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001,          /* lit r0, v1.xxxx              */
12350             0x02000001, 0x80010000, 0x80aa0000};                                /* mov r0.x, v0.z               */
12351     static const DWORD vs_def1[] = {0x02000001, 0x80010000, 0xa0000001};        /* mov r0.x, c1.x               */
12352     static const DWORD vs_def2[] = {0x02000001, 0x80010000, 0xa0550001};        /* mov r0.x, c1.y               */
12353     static const DWORD vs_def3[] = {0x02000001, 0x80010000, 0xa0aa0001};        /* mov r0.x, c1.z               */
12354
12355     static const DWORD vs_footer[] =
12356     {
12357         0x03000005, 0x80020000, 0x80000000, 0xa0ff0000,                         /* mul r0.y, r0.x, c0.w         */
12358         0x0300000d, 0x80040000, 0x80000000, 0x80550000,                         /* sge r0.z, r0.x, r0.y         */
12359         0x0300000d, 0x80020000, 0x80e40000, 0x80000000,                         /* sge r0.y, r0, r0.x           */
12360         0x03000005, 0x80040000, 0x80550000, 0x80e40000,                         /* mul r0.z, r0.y, r0           */
12361         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
12362         0x0300000c, 0x80020000, 0x80000000, 0x80000000,                         /* slt r0.y, r0.x, r0.x         */
12363         0x03000002, 0x80040000, 0x80550000, 0x80550000,                         /* add r0.z, r0.y, r0.y         */
12364         0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000,                         /* slt r0.y, c0.x, r0.w         */
12365         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
12366         0x03000002, 0x80040000, 0x81550000, 0xa0e40000,                         /* add r0.z, -r0.y, c0          */
12367         0x0300000c, 0x80080000, 0xa0000000, 0x80e40000,                         /* slt r0.w, c0.x, r0           */
12368         0x03000005, 0x80040000, 0x80ff0000, 0x80e40000,                         /* mul r0.z, r0.w, r0           */
12369         0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000,             /* mad r0.y, r0.z, c0, r0       */
12370         0x02000001, 0xe0030000, 0x80e40000,                                     /* mov oT0.xy, r0               */
12371         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
12372         0x0000ffff,                                                             /* end                          */
12373     };
12374
12375     static const struct
12376     {
12377         const char *name;
12378         const DWORD *ops;
12379         DWORD size;
12380         D3DCOLOR r500;
12381         D3DCOLOR r600;
12382         D3DCOLOR nv40;
12383         D3DCOLOR nv50;
12384     }
12385     vs_body[] =
12386     {
12387         /* The basic ideas here are:
12388          *     2.0 * +/-INF == +/-INF
12389          *     NAN != NAN
12390          *
12391          * The vertex shader value is written to the red component, with 0.0
12392          * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
12393          * result in 0x00. The pixel shader value is written to the green
12394          * component, but here 0.0 also results in 0x00. The actual value is
12395          * written to the blue component.
12396          *
12397          * There are considerable differences between graphics cards in how
12398          * these are handled, but pow and nrm never generate INF or NAN. */
12399         {"log",     vs_log,     sizeof(vs_log),     0x00000000, 0x00000000, 0x00ff0000, 0x00ff7f00},
12400         {"pow",     vs_pow,     sizeof(vs_pow),     0x000000ff, 0x000000ff, 0x0000ff00, 0x000000ff},
12401         {"nrm",     vs_nrm,     sizeof(vs_nrm),     0x00ff0000, 0x00ff0000, 0x0000ff00, 0x00ff0000},
12402         {"rcp1",    vs_rcp1,    sizeof(vs_rcp1),    0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00},
12403         {"rcp2",    vs_rcp2,    sizeof(vs_rcp2),    0x000000ff, 0x00000000, 0x00ff0000, 0x00ff7f00},
12404         {"rsq1",    vs_rsq1,    sizeof(vs_rsq1),    0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00},
12405         {"rsq2",    vs_rsq2,    sizeof(vs_rsq2),    0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00},
12406         {"lit",     vs_lit,     sizeof(vs_lit),     0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
12407         {"def1",    vs_def1,    sizeof(vs_def1),    0x000000ff, 0x00007f00, 0x0000ff00, 0x00007f00},
12408         {"def2",    vs_def2,    sizeof(vs_def2),    0x00ff0000, 0x00ff7f00, 0x00ff0000, 0x00ff7f00},
12409         {"def3",    vs_def3,    sizeof(vs_def3),    0x00ff00ff, 0x00ff7f00, 0x00ff00ff, 0x00ff7f00},
12410     };
12411
12412     static const DWORD ps_code[] =
12413     {
12414         0xffff0200,                                                             /* ps_2_0                       */
12415         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
12416         0x0200001f, 0x80000000, 0xb0030000,                                     /* dcl t0.xy                    */
12417         0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000,                         /* max r1.x, t0, c0             */
12418         0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000,                         /* min r0.x, t0, c0             */
12419         0x03000002, 0x80010000, 0x80e40000, 0x81e40001,                         /* add r0.x, r0, -r1            */
12420         0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000,             /* mad r1.x, t0, c0.w. -t0      */
12421         0x02000023, 0x80010002, 0x80e40001,                                     /* abs r2.x, r1                 */
12422         0x02000023, 0x80010000, 0x80e40000,                                     /* abs r0.x, r0                 */
12423         0x02000023, 0x80010001, 0xb0e40000,                                     /* abs r1.x, t0                 */
12424         0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r2, c0.z, c0      */
12425         0x02000023, 0x80010002, 0x80e40002,                                     /* abs r2.x, r2                 */
12426         0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r1.x, -r1, c0.z, c0      */
12427         0x02000023, 0x80010001, 0x80e40001,                                     /* abs r1.x, r1                 */
12428         0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r3.x, -r2, c0.z, c0      */
12429         0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r1, c0.z, c0      */
12430         0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000,             /* cmp r0.x, -r0, c0.y, c0      */
12431         0x03000005, 0x80010002, 0x80e40002, 0x80e40003,                         /* mul r2.x, r2, r3             */
12432         0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000,             /* cmp r0.x, -r2, c0.z, r0      */
12433         0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000,             /* cmp r0.y, -r1.x, r0.x, c0.x  */
12434         0x02000001, 0x80050000, 0xb0c90000,                                     /* mov r0.xz, t0.yzxw           */
12435         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.w, c0.z               */
12436         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
12437         0x0000ffff,                                                             /* end                          */
12438     };
12439
12440     struct
12441     {
12442         float x, y, z;
12443         float s;
12444     }
12445     quad[] =
12446     {
12447         { -1.0f,  1.0f, 0.0f, 0.0f},
12448         {  1.0f,  1.0f, 1.0f, 0.0f},
12449         { -1.0f, -1.0f, 0.0f, 0.0f},
12450         {  1.0f, -1.0f, 1.0f, 0.0f},
12451     };
12452
12453     IDirect3DPixelShader9 *ps;
12454     UINT body_size = 0;
12455     DWORD *vs_code;
12456     D3DCAPS9 caps;
12457     HRESULT hr;
12458     UINT i;
12459
12460     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12461     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12462     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12463     {
12464         skip("No shader model 2.0 support, skipping floating point specials test.\n");
12465         return;
12466     }
12467
12468     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
12469     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12470
12471     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12472     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12473     hr = IDirect3DDevice9_SetPixelShader(device, ps);
12474     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12475
12476     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12477     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12478
12479     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
12480     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12481
12482     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12483     {
12484         if (vs_body[i].size > body_size) body_size = vs_body[i].size;
12485     }
12486
12487     vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
12488     memcpy(vs_code, vs_header, sizeof(vs_header));
12489
12490     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12491     {
12492         DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
12493         IDirect3DVertexShader9 *vs;
12494         D3DCOLOR color;
12495
12496         memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
12497         offset += vs_body[i].size / sizeof(*vs_body[i].ops);
12498         memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
12499
12500         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
12501         ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
12502         hr = IDirect3DDevice9_SetVertexShader(device, vs);
12503         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12504
12505         hr = IDirect3DDevice9_BeginScene(device);
12506         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12507         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12508         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12509         hr = IDirect3DDevice9_EndScene(device);
12510         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12511
12512         color = getPixelColor(device, 320, 240);
12513         ok(color_match(color, vs_body[i].r600, 1)
12514                 || color_match(color, vs_body[i].nv40, 1)
12515                 || color_match(color, vs_body[i].nv50, 1),
12516                 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
12517                 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
12518
12519         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12520         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12521
12522         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12523         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12524         IDirect3DVertexShader9_Release(vs);
12525     }
12526
12527     HeapFree(GetProcessHeap(), 0, vs_code);
12528
12529     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12530     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12531     IDirect3DPixelShader9_Release(ps);
12532 }
12533
12534 static void srgbwrite_format_test(IDirect3DDevice9 *device)
12535 {
12536     IDirect3D9 *d3d;
12537     IDirect3DSurface9 *rt, *backbuffer;
12538     IDirect3DTexture9 *texture;
12539     HRESULT hr;
12540     int i;
12541     DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
12542     static const struct
12543     {
12544         D3DFORMAT fmt;
12545         const char *name;
12546     }
12547     formats[] =
12548     {
12549         { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
12550         { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
12551         { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
12552         { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
12553         { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
12554     };
12555     static const struct
12556     {
12557         float x, y, z;
12558         float u, v;
12559     }
12560     quad[] =
12561     {
12562         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12563         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12564         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12565         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12566     };
12567
12568     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12569     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12570     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12571     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12572     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
12573     ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
12574     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12575     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12576     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12577     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12578
12579     for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
12580     {
12581         if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12582                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
12583         {
12584             skip("Format %s not supported as render target, skipping test.\n",
12585                     formats[i].name);
12586             continue;
12587         }
12588
12589         hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
12590                                             D3DPOOL_DEFAULT, &texture, NULL);
12591         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12592         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
12593         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12594
12595         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
12596         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12597         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12598         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12599         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
12600         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12601
12602         hr = IDirect3DDevice9_BeginScene(device);
12603         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12604         if(SUCCEEDED(hr))
12605         {
12606             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
12607             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12608             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
12609             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12610             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12611             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12612
12613             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
12614             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12615             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12616             ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12617             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
12618             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12619             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12620             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12621             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12622             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12623             hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12624             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12625
12626             hr = IDirect3DDevice9_EndScene(device);
12627             ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12628         }
12629
12630         IDirect3DSurface9_Release(rt);
12631         IDirect3DTexture9_Release(texture);
12632
12633         color = getPixelColor(device, 360, 240);
12634         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12635                                     D3DUSAGE_QUERY_SRGBWRITE,
12636                                     D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
12637         {
12638             /* Big slop for R5G6B5 */
12639             ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
12640                 formats[i].name, color_srgb, color);
12641         }
12642         else
12643         {
12644             /* Big slop for R5G6B5 */
12645             ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
12646                 formats[i].name, color_rgb, color);
12647         }
12648
12649         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12650         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12651     }
12652
12653     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12654     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12655
12656     IDirect3D9_Release(d3d);
12657     IDirect3DSurface9_Release(backbuffer);
12658 }
12659
12660 static void ds_size_test(IDirect3DDevice9 *device)
12661 {
12662     IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
12663     HRESULT hr;
12664     DWORD num_passes;
12665     struct
12666     {
12667         float x, y, z;
12668     }
12669     quad[] =
12670     {
12671         {-1.0,  -1.0,   0.0 },
12672         {-1.0,   1.0,   0.0 },
12673         { 1.0,  -1.0,   0.0 },
12674         { 1.0,   1.0,   0.0 }
12675     };
12676
12677     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12678     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12679     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
12680     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
12681     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
12682     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
12683
12684     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12685     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12686     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
12687     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12688     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12689     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12690     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12691     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12692     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12693     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12694     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
12695     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
12696     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12697     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12698     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12699     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12700     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12701     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12702
12703     /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
12704      * but does not change the surface's contents. */
12705     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
12706     ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
12707     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
12708     ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
12709     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
12710     ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12711
12712     /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
12713
12714     /* Turning on any depth-related state results in a ValidateDevice failure */
12715     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12716     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12717     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12718     ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12719         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12720     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12721     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12722     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12723     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12724     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12725     ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12726         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12727
12728     /* Try to draw with the device in an invalid state */
12729     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12730     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12731     hr = IDirect3DDevice9_BeginScene(device);
12732     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12733     if(SUCCEEDED(hr))
12734     {
12735         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12736         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12737         hr = IDirect3DDevice9_EndScene(device);
12738         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12739
12740         /* Don't check the resulting draw unless we find an app that needs it. On nvidia ValidateDevice
12741          * returns CONFLICTINGRENDERSTATE, so the result is undefined. On AMD d3d seems to assume the
12742          * stored Z buffer value is 0.0 for all pixels, even those that are covered by the depth buffer */
12743     }
12744
12745     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12746     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12747     hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12748     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12749     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12750     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12751
12752     IDirect3DSurface9_Release(readback);
12753     IDirect3DSurface9_Release(ds);
12754     IDirect3DSurface9_Release(rt);
12755     IDirect3DSurface9_Release(old_rt);
12756     IDirect3DSurface9_Release(old_ds);
12757 }
12758
12759 static void unbound_sampler_test(IDirect3DDevice9 *device)
12760 {
12761     HRESULT hr;
12762     IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
12763     IDirect3DSurface9 *rt, *old_rt;
12764     DWORD color;
12765
12766     static const DWORD ps_code[] =
12767     {
12768         0xffff0200,                                     /* ps_2_0           */
12769         0x0200001f, 0x90000000, 0xa00f0800,             /* dcl_2d s0        */
12770         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12771         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12772         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12773         0x0000ffff,                                     /* end              */
12774     };
12775     static const DWORD ps_code_cube[] =
12776     {
12777         0xffff0200,                                     /* ps_2_0           */
12778         0x0200001f, 0x98000000, 0xa00f0800,             /* dcl_cube s0      */
12779         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12780         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12781         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12782         0x0000ffff,                                     /* end              */
12783     };
12784     static const DWORD ps_code_volume[] =
12785     {
12786         0xffff0200,                                     /* ps_2_0           */
12787         0x0200001f, 0xa0000000, 0xa00f0800,             /* dcl_volume s0    */
12788         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12789         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12790         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12791         0x0000ffff,                                     /* end              */
12792     };
12793
12794     static const struct
12795     {
12796         float x, y, z;
12797         float u, v;
12798     }
12799     quad[] =
12800     {
12801         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12802         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12803         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12804         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12805     };
12806
12807     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12808     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
12809
12810     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12811     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12812     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
12813     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12814     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
12815     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12816
12817     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
12818     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12819
12820     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12821     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12822
12823     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12824     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12825
12826     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
12827     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12828
12829     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
12830     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
12831
12832     hr = IDirect3DDevice9_SetPixelShader(device, ps);
12833     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12834
12835     hr = IDirect3DDevice9_BeginScene(device);
12836     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12837     if(SUCCEEDED(hr))
12838     {
12839         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12840         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12841
12842         hr = IDirect3DDevice9_EndScene(device);
12843         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12844     }
12845
12846     color = getPixelColorFromSurface(rt, 32, 32);
12847     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12848
12849     /* Now try with a cube texture */
12850     hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
12851     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12852
12853     hr = IDirect3DDevice9_BeginScene(device);
12854     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12855     if (SUCCEEDED(hr))
12856     {
12857         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12858         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12859
12860         hr = IDirect3DDevice9_EndScene(device);
12861         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12862     }
12863
12864     color = getPixelColorFromSurface(rt, 32, 32);
12865     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12866
12867     /* And then with a volume texture */
12868     hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
12869     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12870
12871     hr = IDirect3DDevice9_BeginScene(device);
12872     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12873     if (SUCCEEDED(hr))
12874     {
12875         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12876         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12877
12878         hr = IDirect3DDevice9_EndScene(device);
12879         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12880     }
12881
12882     color = getPixelColorFromSurface(rt, 32, 32);
12883     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12884
12885     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12886     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12887
12888     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12889     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12890
12891     IDirect3DSurface9_Release(rt);
12892     IDirect3DSurface9_Release(old_rt);
12893     IDirect3DPixelShader9_Release(ps);
12894     IDirect3DPixelShader9_Release(ps_cube);
12895     IDirect3DPixelShader9_Release(ps_volume);
12896 }
12897
12898 static void update_surface_test(IDirect3DDevice9 *device)
12899 {
12900     static const BYTE blocks[][8] =
12901     {
12902         {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
12903         {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
12904         {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
12905         {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
12906         {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
12907         {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
12908         {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
12909     };
12910     static const struct
12911     {
12912         UINT x, y;
12913         D3DCOLOR color;
12914     }
12915     expected_colors[] =
12916     {
12917         { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
12918         { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
12919         {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
12920         {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12921         {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12922         {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12923         {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
12924     };
12925     static const struct
12926     {
12927         float x, y, z, w;
12928         float u, v;
12929     }
12930     tri[] =
12931     {
12932         {  0.0f, 480.0f, 0.0f,  1.0f,   0.0f, 0.0f},
12933         {  0.0f,   0.0f, 0.0f,  1.0f,   0.0f, 1.0f},
12934         {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
12935     };
12936     static const RECT rect_2x2 = {0, 0, 2, 2};
12937     static const struct
12938     {
12939         UINT src_level;
12940         UINT dst_level;
12941         const RECT *r;
12942         HRESULT hr;
12943     }
12944     block_size_tests[] =
12945     {
12946         {1, 0, NULL,      D3D_OK},
12947         {0, 1, NULL,      D3DERR_INVALIDCALL},
12948         {5, 4, NULL,      D3DERR_INVALIDCALL},
12949         {4, 5, NULL,      D3DERR_INVALIDCALL},
12950         {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
12951         {5, 5, &rect_2x2, D3D_OK},
12952     };
12953
12954     IDirect3DSurface9 *src_surface, *dst_surface;
12955     IDirect3DTexture9 *src_tex, *dst_tex;
12956     IDirect3D9 *d3d;
12957     UINT count, i;
12958     HRESULT hr;
12959
12960     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12961     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12962
12963     hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12964             D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
12965     IDirect3D9_Release(d3d);
12966     if (FAILED(hr))
12967     {
12968         skip("DXT1 not supported, skipping test.\n");
12969         return;
12970     }
12971
12972     IDirect3D9_Release(d3d);
12973
12974     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
12975     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12976     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
12977     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12978
12979     count = IDirect3DTexture9_GetLevelCount(src_tex);
12980     ok(count == 7, "Got level count %u, expected 7.\n", count);
12981
12982     for (i = 0; i < count; ++i)
12983     {
12984         UINT row_count, block_count, x, y;
12985         D3DSURFACE_DESC desc;
12986         BYTE *row, *block;
12987         D3DLOCKED_RECT r;
12988
12989         hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
12990         ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
12991
12992         hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
12993         ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
12994
12995         row_count = ((desc.Height + 3) & ~3) / 4;
12996         block_count = ((desc.Width + 3) & ~3) / 4;
12997         row = r.pBits;
12998
12999         for (y = 0; y < row_count; ++y)
13000         {
13001             block = row;
13002             for (x = 0; x < block_count; ++x)
13003             {
13004                 memcpy(block, blocks[i], sizeof(blocks[i]));
13005                 block += sizeof(blocks[i]);
13006             }
13007             row += r.Pitch;
13008         }
13009
13010         hr = IDirect3DTexture9_UnlockRect(src_tex, i);
13011         ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
13012     }
13013
13014     for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
13015     {
13016         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
13017         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
13018         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
13019         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
13020
13021         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
13022         ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
13023                 hr, i, block_size_tests[i].hr);
13024
13025         IDirect3DSurface9_Release(dst_surface);
13026         IDirect3DSurface9_Release(src_surface);
13027     }
13028
13029     for (i = 0; i < count; ++i)
13030     {
13031         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
13032         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
13033         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
13034         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
13035
13036         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
13037         ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
13038
13039         IDirect3DSurface9_Release(dst_surface);
13040         IDirect3DSurface9_Release(src_surface);
13041     }
13042
13043     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13044     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13045     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13046     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13047     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
13048     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13049     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
13050     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13051     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
13052     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
13053     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
13054     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
13055
13056     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
13057     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13058
13059     hr = IDirect3DDevice9_BeginScene(device);
13060     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13061     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
13062     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13063     hr = IDirect3DDevice9_EndScene(device);
13064     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13065
13066     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13067     {
13068         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13069         ok(color_match(color, expected_colors[i].color, 0),
13070                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13071                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13072     }
13073
13074     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13075     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13076
13077     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13078     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13079     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
13080     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
13081     IDirect3DTexture9_Release(dst_tex);
13082     IDirect3DTexture9_Release(src_tex);
13083 }
13084
13085 static void multisample_get_rtdata_test(IDirect3DDevice9 *device)
13086 {
13087     IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
13088     IDirect3D9 *d3d9;
13089     HRESULT hr;
13090
13091     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
13092     ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
13093     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13094             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13095     IDirect3D9_Release(d3d9);
13096     if (FAILED(hr))
13097     {
13098         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
13099         return;
13100     }
13101
13102     hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
13103             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13104     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13105     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
13106             D3DPOOL_SYSTEMMEM, &readback, NULL);
13107     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13108
13109     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13110     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13111     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13112     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13113
13114     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13115     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13116     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13117     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13118
13119     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
13120     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13121     hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
13122     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
13123
13124     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13125     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13126     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13127     ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13128
13129     IDirect3DSurface9_Release(original_ds);
13130     IDirect3DSurface9_Release(original_rt);
13131     IDirect3DSurface9_Release(readback);
13132     IDirect3DSurface9_Release(rt);
13133 }
13134
13135 static void multisampled_depth_buffer_test(IDirect3D9 *d3d9)
13136 {
13137     IDirect3DDevice9 *device = 0;
13138     IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
13139     D3DCAPS9 caps;
13140     HRESULT hr;
13141     D3DPRESENT_PARAMETERS present_parameters;
13142     unsigned int i;
13143     static const struct
13144     {
13145         float x, y, z;
13146         D3DCOLOR color;
13147     }
13148     quad_1[] =
13149     {
13150         { -1.0f,  1.0f, 0.0f, 0xffff0000},
13151         {  1.0f,  1.0f, 1.0f, 0xffff0000},
13152         { -1.0f, -1.0f, 0.0f, 0xffff0000},
13153         {  1.0f, -1.0f, 1.0f, 0xffff0000},
13154     },
13155     quad_2[] =
13156     {
13157         { -1.0f,  1.0f, 1.0f, 0xff0000ff},
13158         {  1.0f,  1.0f, 0.0f, 0xff0000ff},
13159         { -1.0f, -1.0f, 1.0f, 0xff0000ff},
13160         {  1.0f, -1.0f, 0.0f, 0xff0000ff},
13161     };
13162     static const struct
13163     {
13164         UINT x, y;
13165         D3DCOLOR color;
13166     }
13167     expected_colors[] =
13168     {
13169         { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13170         {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13171         {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13172         {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13173         { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13174         {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13175         {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13176         {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13177     };
13178
13179     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13180             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13181     if (FAILED(hr))
13182     {
13183         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
13184         return;
13185     }
13186     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13187             D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13188     if (FAILED(hr))
13189     {
13190         skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
13191         return;
13192     }
13193
13194     ZeroMemory(&present_parameters, sizeof(present_parameters));
13195     present_parameters.Windowed = TRUE;
13196     present_parameters.hDeviceWindow = create_window();
13197     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13198     present_parameters.BackBufferWidth = 640;
13199     present_parameters.BackBufferHeight = 480;
13200     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13201     present_parameters.EnableAutoDepthStencil = TRUE;
13202     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13203     present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13204
13205     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13206             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13207             &present_parameters, &device);
13208     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13209
13210     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13211     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13212     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13213     {
13214         skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
13215         goto cleanup;
13216     }
13217
13218     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13219             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13220     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13221     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13222             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13223     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13224
13225     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13226     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13227     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13228     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13229
13230     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13231     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13232     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13233     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13234     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13235     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13236     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13237     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13238     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13239     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13240
13241     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13242     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13243
13244     /* Render onscreen and then offscreen */
13245     hr = IDirect3DDevice9_BeginScene(device);
13246     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13247     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13248     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13249     hr = IDirect3DDevice9_EndScene(device);
13250     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13251
13252     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
13253     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13254     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13255     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13256
13257     hr = IDirect3DDevice9_BeginScene(device);
13258     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13259     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13260     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13261     hr = IDirect3DDevice9_EndScene(device);
13262     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13263
13264     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
13265     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13266
13267     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13268     {
13269         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13270         ok(color_match(color, expected_colors[i].color, 1),
13271                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13272                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13273     }
13274
13275     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13276     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13277     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13278     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13279
13280     /* Render offscreen and then onscreen */
13281     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13282     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13283     IDirect3DSurface9_Release(ds);
13284     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13285             D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13286     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13287     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13288
13289     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13290     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13291
13292     hr = IDirect3DDevice9_BeginScene(device);
13293     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13294     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13295     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13296     hr = IDirect3DDevice9_EndScene(device);
13297     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13298
13299     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13300     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13301     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13302     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13303
13304     hr = IDirect3DDevice9_BeginScene(device);
13305     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13306     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13307     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13308     hr = IDirect3DDevice9_EndScene(device);
13309     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13310
13311     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13312     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13313
13314     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13315     {
13316         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13317         ok(color_match(color, expected_colors[i].color, 1),
13318                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13319                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13320     }
13321
13322     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13323     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13324
13325     IDirect3DSurface9_Release(ds);
13326     IDirect3DSurface9_Release(readback);
13327     IDirect3DSurface9_Release(rt);
13328     IDirect3DSurface9_Release(original_rt);
13329     cleanup_device(device);
13330
13331     ZeroMemory(&present_parameters, sizeof(present_parameters));
13332     present_parameters.Windowed = TRUE;
13333     present_parameters.hDeviceWindow = create_window();
13334     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13335     present_parameters.BackBufferWidth = 640;
13336     present_parameters.BackBufferHeight = 480;
13337     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13338     present_parameters.EnableAutoDepthStencil = TRUE;
13339     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13340     present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13341
13342     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13343             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13344             &present_parameters, &device);
13345     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13346
13347     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
13348     ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
13349
13350     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13351             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13352     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13353     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13354             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13355     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13356     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13357             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
13358     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13359
13360     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13361     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13362     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13363     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13364     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13365     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13366     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13367     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13368
13369     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13370     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13371     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13372     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13373     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13374     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13375     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13376     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13377     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13378     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13379
13380     /* Render to a multisampled offscreen frame buffer and then blit to
13381      * the onscreen (not multisampled) frame buffer. */
13382     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13383     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13384
13385     hr = IDirect3DDevice9_BeginScene(device);
13386     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13387     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13388     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13389     hr = IDirect3DDevice9_EndScene(device);
13390     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13391
13392     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13393     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13394     hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
13395     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13396
13397     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13398     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13399     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13400     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13401
13402     hr = IDirect3DDevice9_BeginScene(device);
13403     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13404     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13405     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13406     hr = IDirect3DDevice9_EndScene(device);
13407     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13408
13409     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13410     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13411
13412     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13413     {
13414         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13415         ok(color_match(color, expected_colors[i].color, 1),
13416                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13417                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13418     }
13419
13420     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13421     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13422
13423     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13424     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13425     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13426     ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13427
13428     IDirect3DSurface9_Release(original_ds);
13429     IDirect3DSurface9_Release(original_rt);
13430     IDirect3DSurface9_Release(ds);
13431     IDirect3DSurface9_Release(readback);
13432     IDirect3DSurface9_Release(rt);
13433 cleanup:
13434     cleanup_device(device);
13435 }
13436
13437 static void resz_test(IDirect3D9 *d3d9)
13438 {
13439     IDirect3DDevice9 *device = 0;
13440     IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
13441     D3DCAPS9 caps;
13442     HRESULT hr;
13443     D3DPRESENT_PARAMETERS present_parameters;
13444     unsigned int i;
13445     static const DWORD ps_code[] =
13446     {
13447         0xffff0200,                                                             /* ps_2_0                       */
13448         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
13449         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
13450         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
13451         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
13452         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
13453         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
13454         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
13455         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
13456         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
13457         0x0000ffff,                                                             /* end                          */
13458     };
13459     struct
13460     {
13461         float x, y, z;
13462         float s, t, p, q;
13463     }
13464     quad[] =
13465     {
13466         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13467         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13468         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13469         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13470     };
13471     struct
13472     {
13473         UINT x, y;
13474         D3DCOLOR color;
13475     }
13476     expected_colors[] =
13477     {
13478         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13479         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13480         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13481         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13482         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13483         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13484         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13485         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13486     };
13487     IDirect3DTexture9 *texture;
13488     IDirect3DPixelShader9 *ps;
13489     DWORD value;
13490
13491     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13492             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13493     if (FAILED(hr))
13494     {
13495         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
13496         return;
13497     }
13498     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13499             D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13500     if (FAILED(hr))
13501     {
13502         skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
13503         return;
13504     }
13505
13506     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13507             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
13508     if (FAILED(hr))
13509     {
13510         skip("No INTZ support, skipping RESZ test.\n");
13511         return;
13512     }
13513
13514     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13515             D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'));
13516     if (FAILED(hr))
13517     {
13518         skip("No RESZ support, skipping RESZ test.\n");
13519         return;
13520     }
13521
13522     ZeroMemory(&present_parameters, sizeof(present_parameters));
13523     present_parameters.Windowed = TRUE;
13524     present_parameters.hDeviceWindow = create_window();
13525     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13526     present_parameters.BackBufferWidth = 640;
13527     present_parameters.BackBufferHeight = 480;
13528     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13529     present_parameters.EnableAutoDepthStencil = FALSE;
13530     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13531     present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13532
13533     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13534             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13535     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13536
13537     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13538     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13539     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
13540     {
13541         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
13542         cleanup_device(device);
13543         return;
13544     }
13545     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13546     {
13547         skip("No unconditional NP2 texture support, skipping INTZ test.\n");
13548         cleanup_device(device);
13549         return;
13550     }
13551
13552     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13553     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13554
13555     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13556             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13557     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13558     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13559             D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13560     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13561             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13562     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13563
13564     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13565             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13566     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13567     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13568     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13569     hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13570     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13571     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13572     ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13573     IDirect3DSurface9_Release(intz_ds);
13574     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13575     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13576
13577     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13578     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13579     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13580     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13581     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13582     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13583     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13584     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13585     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13586     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13587
13588     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13589     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13590     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13591     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13592     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13593     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13594     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13595     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13596     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13597     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13598
13599     /* Render offscreen (multisampled), blit the depth buffer
13600      * into the INTZ texture and then check its contents */
13601     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13602     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13603     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13604     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13605     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13606     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13607
13608     hr = IDirect3DDevice9_BeginScene(device);
13609     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13610     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13611     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13612
13613     /* The destination depth texture has to be bound to sampler 0 */
13614     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13615     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13616
13617     /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
13618     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13619     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13620     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13621     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13622     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13623     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13624     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13625     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13626     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13627     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13628     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13629     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13630     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13631     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13632
13633     /* The actual multisampled depth buffer resolve happens here */
13634     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13635     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13636     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13637     ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13638
13639     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13640     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13641     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13642     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13643
13644     /* Read the depth values back */
13645     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13646     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13647     hr = IDirect3DDevice9_EndScene(device);
13648     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13649
13650     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13651     {
13652         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13653         ok(color_match(color, expected_colors[i].color, 1),
13654                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13655                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13656     }
13657
13658     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13659     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13660
13661     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13662     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13663     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13664     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13665     IDirect3DSurface9_Release(ds);
13666     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13667     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13668     IDirect3DTexture9_Release(texture);
13669     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13670     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13671     IDirect3DPixelShader9_Release(ps);
13672     IDirect3DSurface9_Release(readback);
13673     IDirect3DSurface9_Release(original_rt);
13674     IDirect3DSurface9_Release(rt);
13675     cleanup_device(device);
13676
13677
13678     ZeroMemory(&present_parameters, sizeof(present_parameters));
13679     present_parameters.Windowed = TRUE;
13680     present_parameters.hDeviceWindow = create_window();
13681     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13682     present_parameters.BackBufferWidth = 640;
13683     present_parameters.BackBufferHeight = 480;
13684     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13685     present_parameters.EnableAutoDepthStencil = TRUE;
13686     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13687     present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13688
13689     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13690             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13691     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13692
13693     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13694     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13695     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13696     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13697     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13698             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13699     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13700     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13701             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13702     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13703     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13704     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13705     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13706     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13707     hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13708     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13709     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13710     ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13711     IDirect3DSurface9_Release(intz_ds);
13712     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13713     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13714
13715     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13716     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13717     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13718     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13719     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13720     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13721     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13722     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13723     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13724     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13725
13726     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13727     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13728     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13729     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13730     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13731     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13732     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13733     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13734     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13735     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13736
13737     /* Render onscreen, blit the depth buffer into the INTZ texture
13738      * and then check its contents */
13739     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13740     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13741     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13742     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13743     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13744     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13745
13746     hr = IDirect3DDevice9_BeginScene(device);
13747     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13748     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13749     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13750     hr = IDirect3DDevice9_EndScene(device);
13751     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13752
13753     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13754     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13755
13756     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13757     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13758     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13759     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13760     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13761     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13762     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13763     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13764     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13765     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13766     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13767     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13768     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13769     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13770
13771     /* The actual multisampled depth buffer resolve happens here */
13772     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13773     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13774     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13775     ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13776
13777     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13778     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13779     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13780     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13781
13782     /* Read the depth values back */
13783     hr = IDirect3DDevice9_BeginScene(device);
13784     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13785     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13786     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13787     hr = IDirect3DDevice9_EndScene(device);
13788     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13789
13790     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13791     {
13792         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13793         ok(color_match(color, expected_colors[i].color, 1),
13794                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13795                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13796     }
13797
13798     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13799     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13800
13801
13802     /* Test edge cases - try with no texture at all */
13803     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13804     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13805     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13806     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13807
13808     hr = IDirect3DDevice9_BeginScene(device);
13809     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13810     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13811     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13812     hr = IDirect3DDevice9_EndScene(device);
13813     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13814
13815     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13816     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13817
13818     /* With a non-multisampled depth buffer */
13819     IDirect3DSurface9_Release(ds);
13820     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13821             D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
13822
13823     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13824     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13825     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13826     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13827     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13828     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13829
13830     hr = IDirect3DDevice9_BeginScene(device);
13831     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13832     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13833     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13834
13835     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13836     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13837
13838     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13839     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13840     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13841     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13842     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13843     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13844     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13845     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13846     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13847     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13848     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13849     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13850     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13851     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13852     hr = IDirect3DDevice9_EndScene(device);
13853     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13854
13855     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13856     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13857
13858     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13859     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13860
13861     /* Read the depth values back. */
13862     hr = IDirect3DDevice9_BeginScene(device);
13863     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13864     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13865     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13866     hr = IDirect3DDevice9_EndScene(device);
13867     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13868
13869     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13870     {
13871         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13872         ok(color_match(color, expected_colors[i].color, 1),
13873                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13874                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13875     }
13876
13877     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13878     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13879
13880     /* Without a current depth-stencil buffer set */
13881     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13882     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13883     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13884     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13885
13886     hr = IDirect3DDevice9_BeginScene(device);
13887     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13888     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13889     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13890     hr = IDirect3DDevice9_EndScene(device);
13891     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13892
13893     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13894     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13895
13896     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13897     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13898     IDirect3DSurface9_Release(ds);
13899     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13900     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13901     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13902     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13903     IDirect3DTexture9_Release(texture);
13904     IDirect3DPixelShader9_Release(ps);
13905     IDirect3DSurface9_Release(readback);
13906     IDirect3DSurface9_Release(original_rt);
13907     cleanup_device(device);
13908 }
13909
13910 static void zenable_test(IDirect3DDevice9 *device)
13911 {
13912     static const struct
13913     {
13914         struct vec4 position;
13915         D3DCOLOR diffuse;
13916     }
13917     tquad[] =
13918     {
13919         {{  0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
13920         {{  0.0f,   0.0f, -0.5f, 1.0f}, 0xff00ff00},
13921         {{640.0f, 480.0f,  1.5f, 1.0f}, 0xff00ff00},
13922         {{640.0f,   0.0f,  1.5f, 1.0f}, 0xff00ff00},
13923     };
13924     D3DCOLOR color;
13925     D3DCAPS9 caps;
13926     HRESULT hr;
13927     UINT x, y;
13928     UINT i, j;
13929
13930     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
13931     ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
13932     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13933     ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
13934
13935     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
13936     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13937     hr = IDirect3DDevice9_BeginScene(device);
13938     ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13939     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
13940     ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13941     hr = IDirect3DDevice9_EndScene(device);
13942     ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13943
13944     for (i = 0; i < 4; ++i)
13945     {
13946         for (j = 0; j < 4; ++j)
13947         {
13948             x = 80 * ((2 * j) + 1);
13949             y = 60 * ((2 * i) + 1);
13950             color = getPixelColor(device, x, y);
13951             ok(color_match(color, 0x0000ff00, 1),
13952                     "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
13953         }
13954     }
13955
13956     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13957     ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
13958
13959     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13960     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13961
13962     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
13963             && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
13964     {
13965         static const DWORD vs_code[] =
13966         {
13967             0xfffe0101,                                 /* vs_1_1           */
13968             0x0000001f, 0x80000000, 0x900f0000,         /* dcl_position v0  */
13969             0x00000001, 0xc00f0000, 0x90e40000,         /* mov oPos, v0     */
13970             0x00000001, 0xd00f0000, 0x90e40000,         /* mov oD0, v0      */
13971             0x0000ffff
13972         };
13973         static const DWORD ps_code[] =
13974         {
13975             0xffff0101,                                 /* ps_1_1           */
13976             0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
13977             0x0000ffff                                  /* end              */
13978         };
13979         static const struct vec3 quad[] =
13980         {
13981             {-1.0f, -1.0f, -0.5f},
13982             {-1.0f,  1.0f, -0.5f},
13983             { 1.0f, -1.0f,  1.5f},
13984             { 1.0f,  1.0f,  1.5f},
13985         };
13986         static const D3DCOLOR expected[] =
13987         {
13988             0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
13989             0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
13990             0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
13991             0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
13992         };
13993
13994         IDirect3DVertexShader9 *vs;
13995         IDirect3DPixelShader9 *ps;
13996
13997         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13998         ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
13999         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
14000         ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
14001         hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14002         ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
14003         hr = IDirect3DDevice9_SetVertexShader(device, vs);
14004         ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
14005         hr = IDirect3DDevice9_SetPixelShader(device, ps);
14006         ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
14007
14008         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
14009         ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
14010         hr = IDirect3DDevice9_BeginScene(device);
14011         ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
14012         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14013         ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
14014         hr = IDirect3DDevice9_EndScene(device);
14015         ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
14016
14017         for (i = 0; i < 4; ++i)
14018         {
14019             for (j = 0; j < 4; ++j)
14020             {
14021                 x = 80 * ((2 * j) + 1);
14022                 y = 60 * ((2 * i) + 1);
14023                 color = getPixelColor(device, x, y);
14024                 ok(color_match(color, expected[i * 4 + j], 1),
14025                         "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
14026             }
14027         }
14028
14029         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14030         ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
14031
14032         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14033         ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
14034         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
14035         ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
14036         IDirect3DPixelShader9_Release(ps);
14037         IDirect3DVertexShader9_Release(vs);
14038     }
14039 }
14040
14041 START_TEST(visual)
14042 {
14043     IDirect3D9 *d3d9;
14044     IDirect3DDevice9 *device_ptr;
14045     D3DCAPS9 caps;
14046     HRESULT hr;
14047     DWORD color;
14048
14049     d3d9_handle = LoadLibraryA("d3d9.dll");
14050     if (!d3d9_handle)
14051     {
14052         skip("Could not load d3d9.dll\n");
14053         return;
14054     }
14055
14056     device_ptr = init_d3d9();
14057     if (!device_ptr)
14058     {
14059         skip("Creating the device failed\n");
14060         return;
14061     }
14062
14063     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
14064
14065     /* Check for the reliability of the returned data */
14066     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
14067     if(FAILED(hr))
14068     {
14069         skip("Clear failed, can't assure correctness of the test results, skipping\n");
14070         goto cleanup;
14071     }
14072
14073     color = getPixelColor(device_ptr, 1, 1);
14074     if(color !=0x00ff0000)
14075     {
14076         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
14077         goto cleanup;
14078     }
14079     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
14080
14081     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
14082     if(FAILED(hr))
14083     {
14084         skip("Clear failed, can't assure correctness of the test results, skipping\n");
14085         goto cleanup;
14086     }
14087
14088     color = getPixelColor(device_ptr, 639, 479);
14089     if(color != 0x0000ddee)
14090     {
14091         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
14092         goto cleanup;
14093     }
14094     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
14095
14096     /* Now execute the real tests */
14097     depth_clamp_test(device_ptr);
14098     stretchrect_test(device_ptr);
14099     lighting_test(device_ptr);
14100     clear_test(device_ptr);
14101     color_fill_test(device_ptr);
14102     fog_test(device_ptr);
14103     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
14104     {
14105         test_cube_wrap(device_ptr);
14106     } else {
14107         skip("No cube texture support\n");
14108     }
14109     z_range_test(device_ptr);
14110     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
14111     {
14112         maxmip_test(device_ptr);
14113     }
14114     else
14115     {
14116         skip("No mipmap support\n");
14117     }
14118     offscreen_test(device_ptr);
14119     ds_size_test(device_ptr);
14120     alpha_test(device_ptr);
14121     shademode_test(device_ptr);
14122     srgbtexture_test(device_ptr);
14123     release_buffer_test(device_ptr);
14124     float_texture_test(device_ptr);
14125     g16r16_texture_test(device_ptr);
14126     pixelshader_blending_test(device_ptr);
14127     texture_transform_flags_test(device_ptr);
14128     autogen_mipmap_test(device_ptr);
14129     fixed_function_decl_test(device_ptr);
14130     conditional_np2_repeat_test(device_ptr);
14131     fixed_function_bumpmap_test(device_ptr);
14132     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
14133         stencil_cull_test(device_ptr);
14134     } else {
14135         skip("No two sided stencil support\n");
14136     }
14137     pointsize_test(device_ptr);
14138     tssargtemp_test(device_ptr);
14139     np2_stretch_rect_test(device_ptr);
14140     yuv_color_test(device_ptr);
14141     zwriteenable_test(device_ptr);
14142     alphatest_test(device_ptr);
14143     viewport_test(device_ptr);
14144
14145     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
14146     {
14147         test_constant_clamp_vs(device_ptr);
14148         test_compare_instructions(device_ptr);
14149     }
14150     else skip("No vs_1_1 support\n");
14151
14152     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
14153     {
14154         test_mova(device_ptr);
14155         loop_index_test(device_ptr);
14156         sincos_test(device_ptr);
14157         sgn_test(device_ptr);
14158         clip_planes_test(device_ptr);
14159         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14160             test_vshader_input(device_ptr);
14161             test_vshader_float16(device_ptr);
14162             stream_test(device_ptr);
14163         } else {
14164             skip("No vs_3_0 support\n");
14165         }
14166     }
14167     else skip("No vs_2_0 support\n");
14168
14169     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0) && caps.PixelShaderVersion >= D3DPS_VERSION(2, 0))
14170     {
14171         fog_with_shader_test(device_ptr);
14172     }
14173     else skip("No vs_2_0 and ps_2_0 support\n");
14174
14175     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
14176     {
14177         texbem_test(device_ptr);
14178         texdepth_test(device_ptr);
14179         texkill_test(device_ptr);
14180         x8l8v8u8_test(device_ptr);
14181         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
14182             constant_clamp_ps_test(device_ptr);
14183             cnd_test(device_ptr);
14184             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
14185                 dp2add_ps_test(device_ptr);
14186                 unbound_sampler_test(device_ptr);
14187                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14188                     nested_loop_test(device_ptr);
14189                     pretransformed_varying_test(device_ptr);
14190                     vFace_register_test(device_ptr);
14191                     vpos_register_test(device_ptr);
14192                     multiple_rendertargets_test(device_ptr);
14193                 } else {
14194                     skip("No ps_3_0 or vs_3_0 support\n");
14195                 }
14196             } else {
14197                 skip("No ps_2_0 support\n");
14198             }
14199         }
14200     }
14201     else skip("No ps_1_1 support\n");
14202
14203     texop_test(device_ptr);
14204     texop_range_test(device_ptr);
14205     alphareplicate_test(device_ptr);
14206     dp3_alpha_test(device_ptr);
14207     depth_buffer_test(device_ptr);
14208     depth_buffer2_test(device_ptr);
14209     depth_blit_test(device_ptr);
14210     intz_test(device_ptr);
14211     shadow_test(device_ptr);
14212     fp_special_test(device_ptr);
14213     depth_bounds_test(device_ptr);
14214     srgbwrite_format_test(device_ptr);
14215     update_surface_test(device_ptr);
14216     multisample_get_rtdata_test(device_ptr);
14217     zenable_test(device_ptr);
14218
14219     hr = IDirect3DDevice9_GetDirect3D(device_ptr, &d3d9);
14220     ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
14221     cleanup_device(device_ptr);
14222     device_ptr = NULL;
14223
14224     multisampled_depth_buffer_test(d3d9);
14225     resz_test(d3d9);
14226
14227     IDirect3D9_Release(d3d9);
14228
14229 cleanup:
14230     cleanup_device(device_ptr);
14231 }