d3drm: Fix leakage of pData2 on error.
[wine] / dlls / d3d9 / tests / visual.c
1 /*
2  * Copyright 2005, 2007-2008 Henri Verbeet
3  * Copyright (C) 2007-2008 Stefan Dösinger(for CodeWeavers)
4  * Copyright (C) 2008 Jason Green(for TransGaming)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22  * the framebuffer, read back from there and compared to expected colors.
23  *
24  * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25  * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26  * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27  * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28  * causes visible results in games can be tested in a way that does not depend on pixel exactness
29  */
30
31 #define COBJMACROS
32 #include <d3d9.h>
33 #include "wine/test.h"
34
35 static HMODULE d3d9_handle = 0;
36
37 struct vec3
38 {
39     float x, y, z;
40 };
41
42 struct vec4
43 {
44     float x, y, z, w;
45 };
46
47 static HWND create_window(void)
48 {
49     WNDCLASS wc = {0};
50     HWND ret;
51     wc.lpfnWndProc = DefWindowProc;
52     wc.lpszClassName = "d3d9_test_wc";
53     RegisterClass(&wc);
54
55     ret = CreateWindow("d3d9_test_wc", "d3d9_test",
56                         WS_SYSMENU | WS_POPUP , 0, 0, 640, 480, 0, 0, 0, 0);
57     ShowWindow(ret, SW_SHOW);
58     return ret;
59 }
60
61 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
62 {
63     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
64     c1 >>= 8; c2 >>= 8;
65     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
66     c1 >>= 8; c2 >>= 8;
67     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
68     c1 >>= 8; c2 >>= 8;
69     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
70     return TRUE;
71 }
72
73 /* Locks a given surface and returns the color at (x,y).  It's the caller's
74  * responsibility to only pass in lockable surfaces and valid x,y coordinates */
75 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
76 {
77     DWORD color;
78     HRESULT hr;
79     D3DSURFACE_DESC desc;
80     RECT rectToLock = {x, y, x+1, y+1};
81     D3DLOCKED_RECT lockedRect;
82
83     hr = IDirect3DSurface9_GetDesc(surface, &desc);
84     if(FAILED(hr))  /* This is not a test */
85     {
86         trace("Can't get the surface description, hr=%08x\n", hr);
87         return 0xdeadbeef;
88     }
89
90     hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
91     if(FAILED(hr))  /* This is not a test */
92     {
93         trace("Can't lock the surface, hr=%08x\n", hr);
94         return 0xdeadbeef;
95     }
96     switch(desc.Format) {
97         case D3DFMT_A8R8G8B8:
98         {
99             color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
100             break;
101         }
102         default:
103             trace("Error: unknown surface format: %d\n", desc.Format);
104             color = 0xdeadbeef;
105             break;
106     }
107     hr = IDirect3DSurface9_UnlockRect(surface);
108     if(FAILED(hr))
109     {
110         trace("Can't unlock the surface, hr=%08x\n", hr);
111     }
112     return color;
113 }
114
115 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
116 {
117     DWORD ret;
118     IDirect3DSurface9 *surf = NULL, *target = NULL;
119     HRESULT hr;
120     D3DLOCKED_RECT lockedRect;
121     RECT rectToLock = {x, y, x+1, y+1};
122
123     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480,
124             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
125     if (FAILED(hr) || !surf)
126     {
127         trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
128         return 0xdeadbeef;
129     }
130
131     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
132     if(FAILED(hr))
133     {
134         trace("Can't get the render target, hr=%08x\n", hr);
135         ret = 0xdeadbeed;
136         goto out;
137     }
138
139     hr = IDirect3DDevice9_GetRenderTargetData(device, target, surf);
140     if (FAILED(hr))
141     {
142         trace("Can't read the render target data, hr=%08x\n", hr);
143         ret = 0xdeadbeec;
144         goto out;
145     }
146
147     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
148     if(FAILED(hr))
149     {
150         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
151         ret = 0xdeadbeeb;
152         goto out;
153     }
154
155     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
156      * really important for these tests
157      */
158     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
159     hr = IDirect3DSurface9_UnlockRect(surf);
160     if(FAILED(hr))
161     {
162         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
163     }
164
165 out:
166     if(target) IDirect3DSurface9_Release(target);
167     if(surf) IDirect3DSurface9_Release(surf);
168     return ret;
169 }
170
171 static IDirect3DDevice9 *init_d3d9(void)
172 {
173     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
174     IDirect3D9 *d3d9_ptr = 0;
175     IDirect3DDevice9 *device_ptr = 0;
176     D3DPRESENT_PARAMETERS present_parameters;
177     HRESULT hr;
178     D3DADAPTER_IDENTIFIER9 identifier;
179
180     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
181     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
182     if (!d3d9_create) return NULL;
183
184     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
185     if (!d3d9_ptr)
186     {
187         win_skip("could not create D3D9\n");
188         return NULL;
189     }
190
191     ZeroMemory(&present_parameters, sizeof(present_parameters));
192     present_parameters.Windowed = TRUE;
193     present_parameters.hDeviceWindow = create_window();
194     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
195     present_parameters.BackBufferWidth = 640;
196     present_parameters.BackBufferHeight = 480;
197     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
198     present_parameters.EnableAutoDepthStencil = TRUE;
199     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
200
201     memset(&identifier, 0, sizeof(identifier));
202     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
203     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
204     trace("Driver string: \"%s\"\n", identifier.Driver);
205     trace("Description string: \"%s\"\n", identifier.Description);
206     ok(identifier.Description[0] != '\0', "Empty driver description\n");
207     trace("Device name string: \"%s\"\n", identifier.DeviceName);
208     ok(identifier.DeviceName[0]  != '\0', "Empty device name\n");
209     trace("Driver version %d.%d.%d.%d\n",
210           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
211           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
212
213     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
214             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
215     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
216             "Failed to create a device, hr %#x.\n", hr);
217
218     return device_ptr;
219 }
220
221 static void cleanup_device(IDirect3DDevice9 *device)
222 {
223     if (device)
224     {
225         D3DPRESENT_PARAMETERS present_parameters;
226         IDirect3DSwapChain9 *swapchain;
227         ULONG ref;
228
229         IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
230         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
231         IDirect3DSwapChain9_Release(swapchain);
232         ref = IDirect3DDevice9_Release(device);
233         ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
234         DestroyWindow(present_parameters.hDeviceWindow);
235     }
236 }
237
238 struct vertex
239 {
240     float x, y, z;
241     DWORD diffuse;
242 };
243
244 struct tvertex
245 {
246     float x, y, z, rhw;
247     DWORD diffuse;
248 };
249
250 struct nvertex
251 {
252     float x, y, z;
253     float nx, ny, nz;
254     DWORD diffuse;
255 };
256
257 static void lighting_test(IDirect3DDevice9 *device)
258 {
259     HRESULT hr;
260     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
261     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
262     DWORD color;
263     D3DMATERIAL9 material, old_material;
264     DWORD cop, carg;
265     DWORD old_colorwrite;
266
267     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
268                       0.0f, 1.0f, 0.0f, 0.0f,
269                       0.0f, 0.0f, 1.0f, 0.0f,
270                       0.0f, 0.0f, 0.0f, 1.0f };
271
272     struct vertex unlitquad[] =
273     {
274         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
275         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
276         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
277         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
278     };
279     struct vertex litquad[] =
280     {
281         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
282         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
283         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
284         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
285     };
286     struct nvertex unlitnquad[] =
287     {
288         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
289         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
290         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
291         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
292     };
293     struct nvertex litnquad[] =
294     {
295         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
296         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
297         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
298         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
299     };
300     WORD Indices[] = {0, 1, 2, 2, 3, 0};
301
302     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
303     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
304
305     /* Setup some states that may cause issues */
306     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
307     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
308     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
309     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
310     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
311     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
312     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
313     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
314     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
315     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
316     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
317     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
318     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
319     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
320     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
321     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
322     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
323     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
324     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
325     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
326     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
327     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
328     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &old_colorwrite);
329     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
330     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
331     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
332
333     hr = IDirect3DDevice9_SetFVF(device, 0);
334     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
335
336     hr = IDirect3DDevice9_SetFVF(device, fvf);
337     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
338
339     hr = IDirect3DDevice9_BeginScene(device);
340     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
341     if(hr == D3D_OK)
342     {
343         /* No lights are defined... That means, lit vertices should be entirely black */
344         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
345         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
346         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
347                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
348         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
349
350         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
351         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
352         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
353                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
354         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
355
356         hr = IDirect3DDevice9_SetFVF(device, nfvf);
357         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
358
359         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
360         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
361         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
362                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
363         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
364
365         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
366         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
367         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
368                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
369         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
370
371         hr = IDirect3DDevice9_EndScene(device);
372         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
373     }
374
375     color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
376     ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
377     color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
378     ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
379     color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
380     ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
381     color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
382     ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
383
384     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
385
386     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
387     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
388     memset(&material, 0, sizeof(material));
389     material.Diffuse.r = 0.0;
390     material.Diffuse.g = 0.0;
391     material.Diffuse.b = 0.0;
392     material.Diffuse.a = 1.0;
393     material.Ambient.r = 0.0;
394     material.Ambient.g = 0.0;
395     material.Ambient.b = 0.0;
396     material.Ambient.a = 0.0;
397     material.Specular.r = 0.0;
398     material.Specular.g = 0.0;
399     material.Specular.b = 0.0;
400     material.Specular.a = 0.0;
401     material.Emissive.r = 0.0;
402     material.Emissive.g = 0.0;
403     material.Emissive.b = 0.0;
404     material.Emissive.a = 0.0;
405     material.Power = 0.0;
406     hr = IDirect3DDevice9_SetMaterial(device, &material);
407     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
408
409     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
410     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
411     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
412     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
413
414     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
415     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
416     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
417     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
418     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
419     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
420     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
421     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
422
423     hr = IDirect3DDevice9_BeginScene(device);
424     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
425     if(SUCCEEDED(hr)) {
426         struct vertex lighting_test[] = {
427             {-1.0,   -1.0,   0.1,    0x8000ff00},
428             { 1.0,   -1.0,   0.1,    0x80000000},
429             {-1.0,    1.0,   0.1,    0x8000ff00},
430             { 1.0,    1.0,   0.1,    0x80000000}
431         };
432         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
433         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
434         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
435         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
436
437         hr = IDirect3DDevice9_EndScene(device);
438         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
439     }
440
441     color = getPixelColor(device, 320, 240);
442     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
443     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
444
445     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
446     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
447     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
448     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
449     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
450     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
451     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
452     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
453     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, old_colorwrite);
454     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
455     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
456     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
457     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
458     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
459 }
460
461 static void clear_test(IDirect3DDevice9 *device)
462 {
463     /* Tests the correctness of clearing parameters */
464     HRESULT hr;
465     D3DRECT rect[2];
466     D3DRECT rect_negneg;
467     DWORD color;
468     D3DVIEWPORT9 old_vp, vp;
469     RECT scissor;
470     DWORD oldColorWrite;
471     BOOL invalid_clear_failed = FALSE;
472
473     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
474     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
475
476     /* Positive x, negative y */
477     rect[0].x1 = 0;
478     rect[0].y1 = 480;
479     rect[0].x2 = 320;
480     rect[0].y2 = 240;
481
482     /* Positive x, positive y */
483     rect[1].x1 = 0;
484     rect[1].y1 = 0;
485     rect[1].x2 = 320;
486     rect[1].y2 = 240;
487     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
488      * returns D3D_OK, but ignores the rectangle silently
489      */
490     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
491     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
492     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
493
494     /* negative x, negative y */
495     rect_negneg.x1 = 640;
496     rect_negneg.y1 = 240;
497     rect_negneg.x2 = 320;
498     rect_negneg.y2 = 0;
499     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
500     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
501     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
502
503     color = getPixelColor(device, 160, 360); /* lower left quad */
504     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
505     color = getPixelColor(device, 160, 120); /* upper left quad */
506     if(invalid_clear_failed) {
507         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
508         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
509     } else {
510         /* If the negative rectangle was dropped silently, the correct ones are cleared */
511         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
512     }
513     color = getPixelColor(device, 480, 360); /* lower right quad  */
514     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
515     color = getPixelColor(device, 480, 120); /* upper right quad */
516     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
517
518     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
519
520     /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
521      * clear the red quad in the top left part of the render target. For some reason it
522      * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
523      * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
524      * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
525      * pick some obvious value
526      */
527     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
528     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
529
530     /* Test how the viewport affects clears */
531     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
532     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
533     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
534     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
535
536     vp.X = 160;
537     vp.Y = 120;
538     vp.Width = 160;
539     vp.Height = 120;
540     vp.MinZ = 0.0;
541     vp.MaxZ = 1.0;
542     hr = IDirect3DDevice9_SetViewport(device, &vp);
543     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
544     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
545     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
546
547     vp.X = 320;
548     vp.Y = 240;
549     vp.Width = 320;
550     vp.Height = 240;
551     vp.MinZ = 0.0;
552     vp.MaxZ = 1.0;
553     hr = IDirect3DDevice9_SetViewport(device, &vp);
554     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
555     rect[0].x1 = 160;
556     rect[0].y1 = 120;
557     rect[0].x2 = 480;
558     rect[0].y2 = 360;
559     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
560     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
561
562     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
563     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
564
565     color = getPixelColor(device, 158, 118);
566     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
567     color = getPixelColor(device, 162, 118);
568     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
569     color = getPixelColor(device, 158, 122);
570     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
571     color = getPixelColor(device, 162, 122);
572     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
573
574     color = getPixelColor(device, 318, 238);
575     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
576     color = getPixelColor(device, 322, 238);
577     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
578     color = getPixelColor(device, 318, 242);
579     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
580     color = getPixelColor(device, 322, 242);
581     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
582
583     color = getPixelColor(device, 478, 358);
584     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
585     color = getPixelColor(device, 482, 358);
586     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
587     color = getPixelColor(device, 478, 362);
588     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
589     color = getPixelColor(device, 482, 362);
590     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
591
592     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
593
594     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
595     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
596
597     scissor.left = 160;
598     scissor.right = 480;
599     scissor.top = 120;
600     scissor.bottom = 360;
601     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
602     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
603     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
604     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
605
606     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
607     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
608     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
609     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
610
611     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
612     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
613
614     color = getPixelColor(device, 158, 118);
615     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
616     color = getPixelColor(device, 162, 118);
617     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
618     color = getPixelColor(device, 158, 122);
619     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
620     color = getPixelColor(device, 162, 122);
621     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
622
623     color = getPixelColor(device, 158, 358);
624     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
625     color = getPixelColor(device, 162, 358);
626     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
627     color = getPixelColor(device, 158, 358);
628     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
629     color = getPixelColor(device, 162, 362);
630     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
631
632     color = getPixelColor(device, 478, 118);
633     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
634     color = getPixelColor(device, 478, 122);
635     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
636     color = getPixelColor(device, 482, 122);
637     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
638     color = getPixelColor(device, 482, 358);
639     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
640
641     color = getPixelColor(device, 478, 358);
642     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
643     color = getPixelColor(device, 478, 362);
644     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
645     color = getPixelColor(device, 482, 358);
646     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
647     color = getPixelColor(device, 482, 362);
648     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
649
650     color = getPixelColor(device, 318, 238);
651     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
652     color = getPixelColor(device, 318, 242);
653     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
654     color = getPixelColor(device, 322, 238);
655     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
656     color = getPixelColor(device, 322, 242);
657     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
658
659     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
660
661     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
662     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
663     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
664     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
665
666     /* Same nvidia windows driver trouble with white clears as earlier in the same test */
667     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
668     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
669
670     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
671     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
672
673     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
674     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
675
676     /* Colorwriteenable does not affect the clear */
677     color = getPixelColor(device, 320, 240);
678     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
679
680     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
681 }
682
683 static void color_fill_test(IDirect3DDevice9 *device)
684 {
685     HRESULT hr;
686     IDirect3DSurface9 *backbuffer = NULL;
687     IDirect3DSurface9 *rt_surface = NULL;
688     IDirect3DSurface9 *offscreen_surface = NULL;
689     DWORD fill_color, color;
690
691     /* Test ColorFill on a the backbuffer (should pass) */
692     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
693     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
694     if(backbuffer)
695     {
696         fill_color = 0x112233;
697         hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
698         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
699
700         color = getPixelColor(device, 0, 0);
701         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
702
703         IDirect3DSurface9_Release(backbuffer);
704     }
705
706     /* Test ColorFill on a render target surface (should pass) */
707     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
708     ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
709     if(rt_surface)
710     {
711         fill_color = 0x445566;
712         hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
713         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
714
715         color = getPixelColorFromSurface(rt_surface, 0, 0);
716         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
717
718         IDirect3DSurface9_Release(rt_surface);
719     }
720
721     /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
722     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
723             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
724     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
725     if(offscreen_surface)
726     {
727         fill_color = 0x778899;
728         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
729         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
730
731         color = getPixelColorFromSurface(offscreen_surface, 0, 0);
732         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
733
734         IDirect3DSurface9_Release(offscreen_surface);
735     }
736
737     /* Try ColorFill on a offscreen surface in sysmem (should fail) */
738     offscreen_surface = NULL;
739     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
740             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
741     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
742     if(offscreen_surface)
743     {
744         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
745         ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
746
747         IDirect3DSurface9_Release(offscreen_surface);
748     }
749 }
750
751 typedef struct {
752     float in[4];
753     DWORD out;
754 } test_data_t;
755
756 /*
757  *  c7      mova    ARGB            mov     ARGB
758  * -2.4     -2      0x00ffff00      -3      0x00ff0000
759  * -1.6     -2      0x00ffff00      -2      0x00ffff00
760  * -0.4      0      0x0000ffff      -1      0x0000ff00
761  *  0.4      0      0x0000ffff       0      0x0000ffff
762  *  1.6      2      0x00ff00ff       1      0x000000ff
763  *  2.4      2      0x00ff00ff       2      0x00ff00ff
764  */
765 static void test_mova(IDirect3DDevice9 *device)
766 {
767     static const DWORD mova_test[] = {
768         0xfffe0200,                                                             /* vs_2_0                       */
769         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
770         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
771         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
772         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
773         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
774         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
775         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
776         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
777         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
778         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
779         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
780         0x0000ffff                                                              /* END                          */
781     };
782     static const DWORD mov_test[] = {
783         0xfffe0101,                                                             /* vs_1_1                       */
784         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
785         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
786         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
787         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
788         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
789         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
790         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
791         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
792         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
793         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
794         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
795         0x0000ffff                                                              /* END                          */
796     };
797
798     static const test_data_t test_data[2][6] = {
799         {
800             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
801             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
802             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
803             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
804             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
805             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
806         },
807         {
808             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
809             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
810             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
811             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
812             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
813             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
814         }
815     };
816
817     static const float quad[][3] = {
818         {-1.0f, -1.0f, 0.0f},
819         {-1.0f,  1.0f, 0.0f},
820         { 1.0f, -1.0f, 0.0f},
821         { 1.0f,  1.0f, 0.0f},
822     };
823
824     static const D3DVERTEXELEMENT9 decl_elements[] = {
825         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
826         D3DDECL_END()
827     };
828
829     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
830     IDirect3DVertexShader9 *mova_shader = NULL;
831     IDirect3DVertexShader9 *mov_shader = NULL;
832     HRESULT hr;
833     UINT i, j;
834
835     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
836     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
837     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
838     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
839     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
840     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
841     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
842     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
843
844     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
845     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
846     for(j = 0; j < 2; ++j)
847     {
848         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
849         {
850             DWORD color;
851
852             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
853             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
854
855             hr = IDirect3DDevice9_BeginScene(device);
856             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
857
858             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
859             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
860
861             hr = IDirect3DDevice9_EndScene(device);
862             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
863
864             color = getPixelColor(device, 320, 240);
865             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
866                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
867
868             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
869             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
870
871             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
872             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
873         }
874         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
875         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
876     }
877
878     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
879     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
880
881     IDirect3DVertexDeclaration9_Release(vertex_declaration);
882     IDirect3DVertexShader9_Release(mova_shader);
883     IDirect3DVertexShader9_Release(mov_shader);
884 }
885
886 struct sVertex {
887     float x, y, z;
888     DWORD diffuse;
889     DWORD specular;
890 };
891
892 struct sVertexT {
893     float x, y, z, rhw;
894     DWORD diffuse;
895     DWORD specular;
896 };
897
898 static void fog_test(IDirect3DDevice9 *device)
899 {
900     HRESULT hr;
901     D3DCOLOR color;
902     float start = 0.0f, end = 1.0f;
903     D3DCAPS9 caps;
904     int i;
905
906     /* Gets full z based fog with linear fog, no fog with specular color */
907     struct sVertex untransformed_1[] = {
908         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
909         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
910         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
911         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
912     };
913     /* Ok, I am too lazy to deal with transform matrices */
914     struct sVertex untransformed_2[] = {
915         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
916         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
917         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
918         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
919     };
920     /* Untransformed ones. Give them a different diffuse color to make the test look
921      * nicer. It also makes making sure that they are drawn correctly easier.
922      */
923     struct sVertexT transformed_1[] = {
924         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
925         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
926         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
927         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
928     };
929     struct sVertexT transformed_2[] = {
930         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
931         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
932         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
933         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
934     };
935     struct vertex rev_fog_quads[] = {
936        {-1.0,   -1.0,   0.1,    0x000000ff},
937        {-1.0,    0.0,   0.1,    0x000000ff},
938        { 0.0,    0.0,   0.1,    0x000000ff},
939        { 0.0,   -1.0,   0.1,    0x000000ff},
940
941        { 0.0,   -1.0,   0.9,    0x000000ff},
942        { 0.0,    0.0,   0.9,    0x000000ff},
943        { 1.0,    0.0,   0.9,    0x000000ff},
944        { 1.0,   -1.0,   0.9,    0x000000ff},
945
946        { 0.0,    0.0,   0.4,    0x000000ff},
947        { 0.0,    1.0,   0.4,    0x000000ff},
948        { 1.0,    1.0,   0.4,    0x000000ff},
949        { 1.0,    0.0,   0.4,    0x000000ff},
950
951        {-1.0,    0.0,   0.7,    0x000000ff},
952        {-1.0,    1.0,   0.7,    0x000000ff},
953        { 0.0,    1.0,   0.7,    0x000000ff},
954        { 0.0,    0.0,   0.7,    0x000000ff},
955     };
956     WORD Indices[] = {0, 1, 2, 2, 3, 0};
957
958     const float ident_mat[16] =
959     {
960         1.0f, 0.0f, 0.0f, 0.0f,
961         0.0f, 1.0f, 0.0f, 0.0f,
962         0.0f, 0.0f, 1.0f, 0.0f,
963         0.0f, 0.0f, 0.0f, 1.0f
964     };
965     const float world_mat1[16] =
966     {
967         1.0f, 0.0f,  0.0f, 0.0f,
968         0.0f, 1.0f,  0.0f, 0.0f,
969         0.0f, 0.0f,  1.0f, 0.0f,
970         0.0f, 0.0f, -0.5f, 1.0f
971     };
972     const float world_mat2[16] =
973     {
974         1.0f, 0.0f, 0.0f, 0.0f,
975         0.0f, 1.0f, 0.0f, 0.0f,
976         0.0f, 0.0f, 1.0f, 0.0f,
977         0.0f, 0.0f, 1.0f, 1.0f
978     };
979     const float proj_mat[16] =
980     {
981         1.0f, 0.0f,  0.0f, 0.0f,
982         0.0f, 1.0f,  0.0f, 0.0f,
983         0.0f, 0.0f,  1.0f, 0.0f,
984         0.0f, 0.0f, -1.0f, 1.0f
985     };
986
987     const struct sVertex far_quad1[] =
988     {
989         {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
990         {-1.0f,  0.0f, 0.5f, 0xffff0000, 0xff000000},
991         { 0.0f,  0.0f, 0.5f, 0xffff0000, 0xff000000},
992         { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
993     };
994     const struct sVertex far_quad2[] =
995     {
996         {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
997         {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
998         { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
999         { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1000     };
1001
1002     memset(&caps, 0, sizeof(caps));
1003     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1004     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
1005     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1006     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1007
1008     /* Setup initial states: No lighting, fog on, fog color */
1009     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1010     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1011     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1012     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1013     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1014     ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1015
1016     /* First test: Both table fog and vertex fog off */
1017     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1018     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1019     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1020     ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1021
1022     /* Start = 0, end = 1. Should be default, but set them */
1023     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1024     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1025     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1026     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1027
1028     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1029     {
1030         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1031         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1032         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
1033         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1034                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1035                                                      sizeof(untransformed_1[0]));
1036         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1037
1038         /* That makes it use the Z value */
1039         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1040         ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
1041         /* Untransformed, vertex fog != none (or table fog != none):
1042          * Use the Z value as input into the equation
1043          */
1044         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1045                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1046                                                      sizeof(untransformed_2[0]));
1047         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1048
1049         /* transformed verts */
1050         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1051         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1052         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1053         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1054                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1055                                                      sizeof(transformed_1[0]));
1056         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1057
1058         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1059         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1060         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
1061          * equation
1062          */
1063         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1064                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
1065                                                      sizeof(transformed_2[0]));
1066         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1067
1068         hr = IDirect3DDevice9_EndScene(device);
1069         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1070     }
1071     else
1072     {
1073         ok(FALSE, "BeginScene failed\n");
1074     }
1075
1076     color = getPixelColor(device, 160, 360);
1077     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1078     color = getPixelColor(device, 160, 120);
1079     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1080     color = getPixelColor(device, 480, 120);
1081     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1082     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1083     {
1084         color = getPixelColor(device, 480, 360);
1085         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1086     }
1087     else
1088     {
1089         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1090          * The settings above result in no fogging with vertex fog
1091          */
1092         color = getPixelColor(device, 480, 120);
1093         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1094         trace("Info: Table fog not supported by this device\n");
1095     }
1096     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1097
1098     /* Now test the special case fogstart == fogend */
1099     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1100     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1101
1102     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1103     {
1104         start = 512;
1105         end = 512;
1106         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1107         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1108         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1109         ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1110
1111         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1112         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1113         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1114         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1115         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1116         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1117
1118         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1119          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1120          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1121          * The third transformed quad remains unfogged because the fogcoords are read from the specular
1122          * color and has fixed fogstart and fogend.
1123          */
1124         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1125                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1126                 sizeof(untransformed_1[0]));
1127         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1128         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1129                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1130                 sizeof(untransformed_2[0]));
1131         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1132
1133         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1134         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1135         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1136         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1137                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1138                 sizeof(transformed_1[0]));
1139         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1140
1141         hr = IDirect3DDevice9_EndScene(device);
1142         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1143     }
1144     else
1145     {
1146         ok(FALSE, "BeginScene failed\n");
1147     }
1148     color = getPixelColor(device, 160, 360);
1149     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1150     color = getPixelColor(device, 160, 120);
1151     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1152     color = getPixelColor(device, 480, 120);
1153     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1154     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1155
1156     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1157      * but without shaders it seems to work everywhere
1158      */
1159     end = 0.2;
1160     start = 0.8;
1161     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1162     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1163     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1164     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1165     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1166     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1167
1168     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1169      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1170      * so skip this for now
1171      */
1172     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1173         const char *mode = (i ? "table" : "vertex");
1174         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1175         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1176         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1177         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1178         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1179         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1180         hr = IDirect3DDevice9_BeginScene(device);
1181         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1182         if(SUCCEEDED(hr)) {
1183             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1184                                 4,  5,  6,  6,  7, 4,
1185                                 8,  9, 10, 10, 11, 8,
1186                             12, 13, 14, 14, 15, 12};
1187
1188             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1189                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1190                     sizeof(rev_fog_quads[0]));
1191             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1192
1193             hr = IDirect3DDevice9_EndScene(device);
1194             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1195         }
1196         color = getPixelColor(device, 160, 360);
1197         ok(color_match(color, 0x0000ff00, 1),
1198                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1199
1200         color = getPixelColor(device, 160, 120);
1201         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1202                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1203
1204         color = getPixelColor(device, 480, 120);
1205         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1206                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1207
1208         color = getPixelColor(device, 480, 360);
1209         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1210
1211         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1212
1213         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1214             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1215             break;
1216         }
1217     }
1218
1219     if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1220     {
1221         /* A simple fog + non-identity world matrix test */
1222         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat1);
1223         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
1224
1225         start = 0.0;
1226         end = 1.0;
1227         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1228         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1229         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1230         ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1231         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1232         ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1233         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1234         ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1235
1236         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1237         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
1238
1239         if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1240         {
1241             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1242             ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1243
1244             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1245                     2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1246             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1247
1248             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1249                     2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1250             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1251
1252             hr = IDirect3DDevice9_EndScene(device);
1253             ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1254         }
1255         else
1256         {
1257             ok(FALSE, "BeginScene failed\n");
1258         }
1259
1260         color = getPixelColor(device, 160, 360);
1261         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
1262                 "Unfogged quad has color %08x\n", color);
1263         color = getPixelColor(device, 160, 120);
1264         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1265                 "Fogged out quad has color %08x\n", color);
1266
1267         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1268
1269         /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
1270         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat2);
1271         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1272         hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)proj_mat);
1273         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1274
1275         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1276         ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1277
1278         if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1279         {
1280             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1281             ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1282
1283             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1284                     2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1285             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1286
1287             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1288                     2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1289             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1290
1291             hr = IDirect3DDevice9_EndScene(device);
1292             ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1293         }
1294         else
1295         {
1296             ok(FALSE, "BeginScene failed\n");
1297         }
1298
1299         color = getPixelColor(device, 160, 360);
1300         todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1301         color = getPixelColor(device, 160, 120);
1302         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1303                 "Fogged out quad has color %08x\n", color);
1304
1305         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1306
1307         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)ident_mat);
1308         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1309         hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)ident_mat);
1310         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1311     }
1312     else
1313     {
1314         skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1315     }
1316
1317     /* Test RANGEFOG vs FOGTABLEMODE */
1318     if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
1319             (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
1320     {
1321         struct sVertex untransformed_3[] =
1322         {
1323             {-1.0,-1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1324             {-1.0, 1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1325             { 1.0,-1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1326             { 1.0, 1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1327         };
1328
1329         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1330         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
1331         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1332         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
1333
1334         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
1335         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1336
1337         /* z=0.4999, set the fogstart to 0.5 and fogend slightly higher. If range fog
1338          * is not used, the fog coordinate will be equal to fogstart and the quad not
1339          * fogged. If range fog is used the fog coordinate will be slightly higher and
1340          * the fog coordinate will be > fogend, so we get a fully fogged quad. The fog
1341          * is calculated per vertex and interpolated, so even the center of the screen
1342          * where the difference doesn't matter will be fogged, but check the corners in
1343          * case a d3d/gl implementation decides to calculate the fog factor per fragment */
1344         start = 0.5f;
1345         end = 0.50001f;
1346         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1347         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1348         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1349         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1350
1351         /* Table fog: Range fog is not used */
1352         hr = IDirect3DDevice9_BeginScene(device);
1353         ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
1354         if (SUCCEEDED(hr))
1355         {
1356             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1357             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1358             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1359             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1360             hr = IDirect3DDevice9_EndScene(device);
1361             ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1362         }
1363         color = getPixelColor(device, 10, 10);
1364         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1365         color = getPixelColor(device, 630, 10);
1366         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1367         color = getPixelColor(device, 10, 470);
1368         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1369         color = getPixelColor(device, 630, 470);
1370         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1371
1372         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1373         ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1374
1375         /* Vertex fog: Rangefog is used */
1376         hr = IDirect3DDevice9_BeginScene(device);
1377         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP returned %#08x\n", hr);
1378         if (SUCCEEDED(hr))
1379         {
1380             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1381             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1382             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1383             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1384             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1385             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1386             hr = IDirect3DDevice9_EndScene(device);
1387             ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1388         }
1389         color = getPixelColor(device, 10, 10);
1390         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1391                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1392         color = getPixelColor(device, 630, 10);
1393         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1394                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1395         color = getPixelColor(device, 10, 470);
1396         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1397                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1398         color = getPixelColor(device, 630, 470);
1399         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1400                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1401
1402         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1403         ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1404
1405         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
1406         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1407     }
1408     else
1409     {
1410         skip("Range fog or table fog not supported, skipping range fog tests\n");
1411     }
1412
1413     /* Turn off the fog master switch to avoid confusing other tests */
1414     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1415     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1416     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1417     ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1418     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1419     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1420 }
1421
1422 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1423  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1424  * regardless of the actual addressing mode set. The way this test works is
1425  * that we sample in one of the corners of the cubemap with filtering enabled,
1426  * and check the interpolated color. There are essentially two reasonable
1427  * things an implementation can do: Either pick one of the faces and
1428  * interpolate the edge texel with itself (i.e., clamp within the face), or
1429  * interpolate between the edge texels of the three involved faces. It should
1430  * never involve the border color or the other side (texcoord wrapping) of a
1431  * face in the interpolation. */
1432 static void test_cube_wrap(IDirect3DDevice9 *device)
1433 {
1434     static const float quad[][6] = {
1435         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1436         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1437         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1438         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1439     };
1440
1441     static const D3DVERTEXELEMENT9 decl_elements[] = {
1442         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1443         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1444         D3DDECL_END()
1445     };
1446
1447     static const struct {
1448         D3DTEXTUREADDRESS mode;
1449         const char *name;
1450     } address_modes[] = {
1451         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1452         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1453         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1454         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1455         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1456     };
1457
1458     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1459     IDirect3DCubeTexture9 *texture = NULL;
1460     IDirect3DSurface9 *surface = NULL;
1461     IDirect3DSurface9 *face_surface;
1462     D3DLOCKED_RECT locked_rect;
1463     HRESULT hr;
1464     UINT x;
1465     INT y, face;
1466
1467     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1468     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1469     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1470     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1471
1472     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1473             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1474     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1475
1476     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1477             D3DPOOL_DEFAULT, &texture, NULL);
1478     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1479
1480     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1481     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1482
1483     for (y = 0; y < 128; ++y)
1484     {
1485         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1486         for (x = 0; x < 64; ++x)
1487         {
1488             *ptr++ = 0xff0000ff;
1489         }
1490         for (x = 64; x < 128; ++x)
1491         {
1492             *ptr++ = 0xffff0000;
1493         }
1494     }
1495
1496     hr = IDirect3DSurface9_UnlockRect(surface);
1497     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1498
1499     hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1500     ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1501
1502     hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1503     ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1504
1505     IDirect3DSurface9_Release(face_surface);
1506
1507     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1508     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1509
1510     for (y = 0; y < 128; ++y)
1511     {
1512         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1513         for (x = 0; x < 64; ++x)
1514         {
1515             *ptr++ = 0xffff0000;
1516         }
1517         for (x = 64; x < 128; ++x)
1518         {
1519             *ptr++ = 0xff0000ff;
1520         }
1521     }
1522
1523     hr = IDirect3DSurface9_UnlockRect(surface);
1524     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1525
1526     /* Create cube faces */
1527     for (face = 1; face < 6; ++face)
1528     {
1529         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1530         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1531
1532         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1533         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1534
1535         IDirect3DSurface9_Release(face_surface);
1536     }
1537
1538     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1539     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1540
1541     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1542     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1543     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1544     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1545     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1546     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1547
1548     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1549     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1550
1551     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1552     {
1553         DWORD color;
1554
1555         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1556         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1557         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1558         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1559
1560         hr = IDirect3DDevice9_BeginScene(device);
1561         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1562
1563         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1564         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1565
1566         hr = IDirect3DDevice9_EndScene(device);
1567         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1568
1569         color = getPixelColor(device, 320, 240);
1570         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1571                 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1572                 color, address_modes[x].name);
1573
1574         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1575         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1576
1577         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1578         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1579     }
1580
1581     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1582     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1583
1584     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1585     IDirect3DCubeTexture9_Release(texture);
1586     IDirect3DSurface9_Release(surface);
1587 }
1588
1589 static void offscreen_test(IDirect3DDevice9 *device)
1590 {
1591     HRESULT hr;
1592     IDirect3DTexture9 *offscreenTexture = NULL;
1593     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1594     DWORD color;
1595
1596     static const float quad[][5] = {
1597         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1598         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1599         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1600         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1601     };
1602
1603     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1604     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1605
1606     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1607     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1608     if(!offscreenTexture) {
1609         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1610         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1611         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1612         if(!offscreenTexture) {
1613             skip("Cannot create an offscreen render target\n");
1614             goto out;
1615         }
1616     }
1617
1618     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1619     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1620     if(!backbuffer) {
1621         goto out;
1622     }
1623
1624     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1625     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1626     if(!offscreen) {
1627         goto out;
1628     }
1629
1630     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1631     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1632
1633     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1634     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1635     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1636     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1637     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1638     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1639     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1640     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1641     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1642     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1643
1644     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1645         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1646         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1647         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1648         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1649
1650         /* Draw without textures - Should result in a white quad */
1651         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1652         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1653
1654         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1655         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1656         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1657         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1658
1659         /* This time with the texture */
1660         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1661         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1662
1663         IDirect3DDevice9_EndScene(device);
1664     }
1665
1666     /* Center quad - should be white */
1667     color = getPixelColor(device, 320, 240);
1668     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1669     /* Some quad in the cleared part of the texture */
1670     color = getPixelColor(device, 170, 240);
1671     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1672     /* Part of the originally cleared back buffer */
1673     color = getPixelColor(device, 10, 10);
1674     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1675     if(0) {
1676         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1677          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1678          * the offscreen rendering mode this test would succeed or fail
1679          */
1680         color = getPixelColor(device, 10, 470);
1681         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1682     }
1683
1684     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1685
1686 out:
1687     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1688     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1689
1690     /* restore things */
1691     if (backbuffer)
1692     {
1693         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1694         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1695         IDirect3DSurface9_Release(backbuffer);
1696     }
1697     if(offscreenTexture) {
1698         IDirect3DTexture9_Release(offscreenTexture);
1699     }
1700     if(offscreen) {
1701         IDirect3DSurface9_Release(offscreen);
1702     }
1703 }
1704
1705 /* This test tests fog in combination with shaders.
1706  * What's tested: linear fog (vertex and table) with pixel shader
1707  *                linear table fog with non foggy vertex shader
1708  *                vertex fog with foggy vertex shader, non-linear
1709  *                fog with shader, non-linear fog with foggy shader,
1710  *                linear table fog with foggy shader
1711  */
1712 static void fog_with_shader_test(IDirect3DDevice9 *device)
1713 {
1714     HRESULT hr;
1715     DWORD color;
1716     union {
1717         float f;
1718         DWORD i;
1719     } start, end;
1720     unsigned int i, j;
1721
1722     /* basic vertex shader without fog computation ("non foggy") */
1723     static const DWORD vertex_shader_code1[] =
1724     {
1725         0xfffe0101,                                                             /* vs_1_1                       */
1726         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1727         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1728         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1729         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1730         0x0000ffff
1731     };
1732     /* basic vertex shader with reversed fog computation ("foggy") */
1733     static const DWORD vertex_shader_code2[] =
1734     {
1735         0xfffe0101,                                                             /* vs_1_1                        */
1736         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1737         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1738         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1739         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1740         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1741         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1742         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1743         0x0000ffff
1744     };
1745     /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
1746     static const DWORD vertex_shader_code3[] =
1747     {
1748         0xfffe0200,                                                             /* vs_2_0                        */
1749         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1750         0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1751         0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1752         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1753         0x02000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1754         0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1755         0x03000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1756         0x0000ffff
1757     };
1758     /* basic pixel shader */
1759     static const DWORD pixel_shader_code[] =
1760     {
1761         0xffff0101,                                                             /* ps_1_1     */
1762         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0 */
1763         0x0000ffff
1764     };
1765     static const DWORD pixel_shader_code2[] =
1766     {
1767         0xffff0200,                                                             /* ps_2_0     */
1768         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0 */
1769         0x02000001, 0x800f0800, 0x90e40000,                                     /* mov oC0, v0 */
1770         0x0000ffff
1771     };
1772
1773     static struct vertex quad[] = {
1774         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1775         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1776         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1777         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1778     };
1779
1780     static const D3DVERTEXELEMENT9 decl_elements[] = {
1781         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1782         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1783         D3DDECL_END()
1784     };
1785
1786     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1787     IDirect3DVertexShader9      *vertex_shader[4]   = {NULL, NULL, NULL, NULL};
1788     IDirect3DPixelShader9       *pixel_shader[3]    = {NULL, NULL, NULL};
1789
1790     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1791     static const struct test_data_t {
1792         int vshader;
1793         int pshader;
1794         D3DFOGMODE vfog;
1795         D3DFOGMODE tfog;
1796         unsigned int color[11];
1797     } test_data[] = {
1798         /* only pixel shader: */
1799         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1800         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1801         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1802         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1803         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1804         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1805         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1806         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1807         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1808         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1809         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1810         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1811         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1812         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1813         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1814
1815         /* vertex shader */
1816         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1817         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1818          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1819         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1820         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1821         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1822         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1823         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1824         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1825
1826         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1827         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1828         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1829         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1830         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1831         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1832
1833         /* vertex shader and pixel shader */
1834         /* The next 4 tests would read the fog coord output, but it isn't available.
1835          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1836          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1837          * These tests should be disabled if some other hardware behaves differently
1838          */
1839         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1840         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1841         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1842         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1843         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1844         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1845         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1846         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1847         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1848         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1849         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1850         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1851
1852         /* These use the Z coordinate with linear table fog */
1853         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1854         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1855         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1856         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1857         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1858         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1859         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1860         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1861         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1862         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1863         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1864         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1865
1866         /* Non-linear table fog without fog coord */
1867         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1868         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1869         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1870         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1871         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1872         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1873
1874         /* These tests fail on older Nvidia drivers */
1875         /* foggy vertex shader */
1876         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1877         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1878          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1879         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1880         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1881          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1882         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1883         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1884          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1885         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1886         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1887          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1888
1889         {3, 0, D3DFOG_NONE, D3DFOG_NONE,
1890         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1891          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1892         {3, 0, D3DFOG_EXP, D3DFOG_NONE,
1893         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1894          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1895         {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
1896         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1897          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1898         {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1899         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1900          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1901
1902         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1903          * all using the fixed fog-coord linear fog
1904          */
1905         /* vs_1_1 with ps_1_1 */
1906         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1907         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1908          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1909         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1910         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1911          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1912         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1913         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1914          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1915         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1916         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1917          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1918
1919         /* vs_2_0 with ps_1_1 */
1920         {3, 1, D3DFOG_NONE, D3DFOG_NONE,
1921         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1922          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1923         {3, 1, D3DFOG_EXP, D3DFOG_NONE,
1924         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1925          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1926         {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
1927         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1928          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1929         {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1930         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1931          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1932
1933         /* vs_1_1 with ps_2_0 */
1934         {2, 2, D3DFOG_NONE, D3DFOG_NONE,
1935         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1936          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1937         {2, 2, D3DFOG_EXP, D3DFOG_NONE,
1938         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1939          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1940         {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
1941         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1942          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1943         {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
1944         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1945          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1946
1947         /* vs_2_0 with ps_2_0 */
1948         {3, 2, D3DFOG_NONE, D3DFOG_NONE,
1949         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1950          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1951         {3, 2, D3DFOG_EXP, D3DFOG_NONE,
1952         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1953          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1954         {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
1955         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1956          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1957         {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
1958         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1959          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1960
1961         /* These use table fog. Here the shader-provided fog coordinate is
1962          * ignored and the z coordinate used instead
1963          */
1964         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1965         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1966         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1967         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1968         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1969         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1970         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1971         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1972         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1973     };
1974
1975     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1976     start.f=0.1f;
1977     end.f=0.9f;
1978
1979     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1980     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1981     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1982     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1983     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
1984     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1985     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1986     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1987     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
1988     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1989     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1990     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1991
1992     /* Setup initial states: No lighting, fog on, fog color */
1993     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1994     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1995     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1996     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1997     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1998     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1999     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2000     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2001
2002     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2003     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
2004     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2005     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
2006
2007     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
2008     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
2009     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
2010     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
2011     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
2012
2013     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
2014     {
2015         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
2016         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2017         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
2018         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2019         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
2020         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2021         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
2022         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2023
2024         for(j=0; j < 11; j++)
2025         {
2026             /* Don't use the whole zrange to prevent rounding errors */
2027             quad[0].z = 0.001f + (float)j / 10.02f;
2028             quad[1].z = 0.001f + (float)j / 10.02f;
2029             quad[2].z = 0.001f + (float)j / 10.02f;
2030             quad[3].z = 0.001f + (float)j / 10.02f;
2031
2032             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2033             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2034
2035             hr = IDirect3DDevice9_BeginScene(device);
2036             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
2037
2038             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2039             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2040
2041             hr = IDirect3DDevice9_EndScene(device);
2042             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
2043
2044             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
2045             color = getPixelColor(device, 128, 240);
2046             ok(color_match(color, test_data[i].color[j], 13),
2047                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
2048                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
2049
2050             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2051         }
2052     }
2053
2054     /* reset states */
2055     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2056     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2057     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2058     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2059     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2060     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2061     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
2062     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
2063
2064     IDirect3DVertexShader9_Release(vertex_shader[1]);
2065     IDirect3DVertexShader9_Release(vertex_shader[2]);
2066     IDirect3DVertexShader9_Release(vertex_shader[3]);
2067     IDirect3DPixelShader9_Release(pixel_shader[1]);
2068     IDirect3DPixelShader9_Release(pixel_shader[2]);
2069     IDirect3DVertexDeclaration9_Release(vertex_declaration);
2070 }
2071
2072 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
2073     unsigned int i, x, y;
2074     HRESULT hr;
2075     IDirect3DTexture9 *texture[2] = {NULL, NULL};
2076     D3DLOCKED_RECT locked_rect;
2077
2078     /* Generate the textures */
2079     for(i=0; i<2; i++)
2080     {
2081         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
2082                                             D3DPOOL_MANAGED, &texture[i], NULL);
2083         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
2084
2085         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
2086         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2087         for (y = 0; y < 128; ++y)
2088         {
2089             if(i)
2090             { /* Set up black texture with 2x2 texel white spot in the middle */
2091                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2092                 for (x = 0; x < 128; ++x)
2093                 {
2094                     if(y>62 && y<66 && x>62 && x<66)
2095                         *ptr++ = 0xffffffff;
2096                     else
2097                         *ptr++ = 0xff000000;
2098                 }
2099             }
2100             else
2101             { /* Set up a displacement map which points away from the center parallel to the closest axis.
2102                * (if multiplied with bumpenvmat)
2103               */
2104                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2105                 for (x = 0; x < 128; ++x)
2106                 {
2107                     if(abs(x-64)>abs(y-64))
2108                     {
2109                         if(x < 64)
2110                             *ptr++ = 0xc000;
2111                         else
2112                             *ptr++ = 0x4000;
2113                     }
2114                     else
2115                     {
2116                         if(y < 64)
2117                             *ptr++ = 0x0040;
2118                         else
2119                             *ptr++ = 0x00c0;
2120                     }
2121                 }
2122             }
2123         }
2124         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2125         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2126
2127         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2128         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2129
2130         /* Disable texture filtering */
2131         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2132         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2133         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2134         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2135
2136         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2137         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2138         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2139         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2140     }
2141 }
2142
2143 /* test the behavior of the texbem instruction
2144  * with normal 2D and projective 2D textures
2145  */
2146 static void texbem_test(IDirect3DDevice9 *device)
2147 {
2148     HRESULT hr;
2149     DWORD color;
2150     int i;
2151
2152     static const DWORD pixel_shader_code[] = {
2153         0xffff0101,                         /* ps_1_1*/
2154         0x00000042, 0xb00f0000,             /* tex t0*/
2155         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2156         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
2157         0x0000ffff
2158     };
2159     static const DWORD double_texbem_code[] =  {
2160         0xffff0103,                                         /* ps_1_3           */
2161         0x00000042, 0xb00f0000,                             /* tex t0           */
2162         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
2163         0x00000042, 0xb00f0002,                             /* tex t2           */
2164         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
2165         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
2166         0x0000ffff                                          /* end              */
2167     };
2168
2169
2170     static const float quad[][7] = {
2171         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
2172         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
2173         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
2174         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
2175     };
2176     static const float quad_proj[][9] = {
2177         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
2178         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
2179         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
2180         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
2181     };
2182
2183     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
2184         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2185         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2186         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2187         D3DDECL_END()
2188     },{
2189         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2190         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2191         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2192         D3DDECL_END()
2193     } };
2194
2195     /* use asymmetric matrix to test loading */
2196     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
2197
2198     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2199     IDirect3DPixelShader9       *pixel_shader       = NULL;
2200     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
2201     D3DLOCKED_RECT locked_rect;
2202
2203     generate_bumpmap_textures(device);
2204
2205     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2206     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2207     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2208     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2209     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
2210
2211     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2212     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2213
2214     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2215     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2216
2217     for(i=0; i<2; i++)
2218     {
2219         if(i)
2220         {
2221             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
2222             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2223         }
2224
2225         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
2226         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2227         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2228         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2229
2230         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
2231         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2232         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2233         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2234
2235         hr = IDirect3DDevice9_BeginScene(device);
2236         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2237
2238         if(!i)
2239             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2240         else
2241             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
2242         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2243
2244         hr = IDirect3DDevice9_EndScene(device);
2245         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2246
2247         color = getPixelColor(device, 320-32, 240);
2248         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2249         color = getPixelColor(device, 320+32, 240);
2250         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2251         color = getPixelColor(device, 320, 240-32);
2252         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2253         color = getPixelColor(device, 320, 240+32);
2254         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2255
2256         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2257         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2258
2259         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2260         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2261         IDirect3DPixelShader9_Release(pixel_shader);
2262
2263         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2264         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2265         IDirect3DVertexDeclaration9_Release(vertex_declaration);
2266     }
2267
2268     /* clean up */
2269     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2270     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2271
2272     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2273     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2274
2275     for(i=0; i<2; i++)
2276     {
2277         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
2278         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
2279         IDirect3DTexture9_Release(texture); /* For the GetTexture */
2280         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2281         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2282         IDirect3DTexture9_Release(texture);
2283     }
2284
2285     /* Test double texbem */
2286     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
2287     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2288     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
2289     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2290     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
2291     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2292     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
2293     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2294
2295     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
2296     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2297     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
2298     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
2299
2300     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2301     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2302
2303     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
2304     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2305     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
2306     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
2307     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
2308     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2309
2310     {
2311         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
2312 #define tex  0x00ff0000
2313 #define tex1 0x0000ff00
2314 #define origin 0x000000ff
2315         static const DWORD pixel_data[] = {
2316             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2317             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2318             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2319             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2320             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
2321             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2322             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2323             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2324         };
2325 #undef tex1
2326 #undef tex2
2327 #undef origin
2328
2329         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
2330         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2331         for(i = 0; i < 8; i++) {
2332             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
2333         }
2334         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
2335         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2336     }
2337
2338     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2339     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2340     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
2341     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2342     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
2343     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2344     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2345     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2346     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2347     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2348     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2349     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2350
2351     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
2352     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
2353     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2354     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2355     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2356     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2357     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2358     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2359     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2360     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2361
2362     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2363     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2364     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2365     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2366     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2367     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2368     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2369     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2370     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2371     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2372
2373     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2374     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2375     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2376     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2377     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2378     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2379     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2380     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2381     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2382     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2383     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2384     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2385     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2386     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2387     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2388     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2389
2390     hr = IDirect3DDevice9_BeginScene(device);
2391     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2392     if(SUCCEEDED(hr)) {
2393         static const float double_quad[] = {
2394             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2395              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2396             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2397              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2398         };
2399
2400         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2401         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2402         hr = IDirect3DDevice9_EndScene(device);
2403         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2404     }
2405     color = getPixelColor(device, 320, 240);
2406     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2407
2408     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2409     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2410     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2411     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2412     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2413     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2414     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2415     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2416     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2417     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2418
2419     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2420     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2421
2422     IDirect3DPixelShader9_Release(pixel_shader);
2423     IDirect3DTexture9_Release(texture);
2424     IDirect3DTexture9_Release(texture1);
2425     IDirect3DTexture9_Release(texture2);
2426 }
2427
2428 static void z_range_test(IDirect3DDevice9 *device)
2429 {
2430     const struct vertex quad[] =
2431     {
2432         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2433         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2434         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2435         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2436     };
2437     const struct vertex quad2[] =
2438     {
2439         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2440         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2441         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2442         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2443     };
2444
2445     const struct tvertex quad3[] =
2446     {
2447         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2448         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2449         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2450         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2451     };
2452     const struct tvertex quad4[] =
2453     {
2454         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2455         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2456         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2457         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2458     };
2459     HRESULT hr;
2460     DWORD color;
2461     IDirect3DVertexShader9 *shader;
2462     IDirect3DVertexDeclaration9 *decl;
2463     D3DCAPS9 caps;
2464     const DWORD shader_code[] = {
2465         0xfffe0101,                                     /* vs_1_1           */
2466         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2467         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2468         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2469         0x0000ffff                                      /* end              */
2470     };
2471     static const D3DVERTEXELEMENT9 decl_elements[] = {
2472         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2473         D3DDECL_END()
2474     };
2475
2476     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2477
2478     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2479      * then call Present. Then clear the color buffer to make sure it has some defined content
2480      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2481      * by the depth value.
2482      */
2483     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2484     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2485     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2486     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2487     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2488     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2489
2490     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2491     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2492     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2493     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2494     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2495     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2496     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2497     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2498     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2499     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2500
2501     hr = IDirect3DDevice9_BeginScene(device);
2502     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2503     if(hr == D3D_OK)
2504     {
2505         /* Test the untransformed vertex path */
2506         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2507         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2508         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2509         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2510         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2511         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2512
2513         /* Test the transformed vertex path */
2514         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2515         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2516
2517         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2518         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2519         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2520         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2521         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2522         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2523
2524         hr = IDirect3DDevice9_EndScene(device);
2525         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2526     }
2527
2528     /* Do not test the exact corner pixels, but go pretty close to them */
2529
2530     /* Clipped because z > 1.0 */
2531     color = getPixelColor(device, 28, 238);
2532     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2533     color = getPixelColor(device, 28, 241);
2534     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2535     {
2536         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2537     }
2538     else
2539     {
2540         ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2541     }
2542
2543     /* Not clipped, > z buffer clear value(0.75) */
2544     color = getPixelColor(device, 31, 238);
2545     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2546     color = getPixelColor(device, 31, 241);
2547     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2548     color = getPixelColor(device, 100, 238);
2549     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2550     color = getPixelColor(device, 100, 241);
2551     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2552
2553     /* Not clipped, < z buffer clear value */
2554     color = getPixelColor(device, 104, 238);
2555     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2556     color = getPixelColor(device, 104, 241);
2557     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2558     color = getPixelColor(device, 318, 238);
2559     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2560     color = getPixelColor(device, 318, 241);
2561     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2562
2563     /* Clipped because z < 0.0 */
2564     color = getPixelColor(device, 321, 238);
2565     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2566     color = getPixelColor(device, 321, 241);
2567     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2568     {
2569         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2570     }
2571     else
2572     {
2573         ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2574     }
2575
2576     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2577     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2578
2579     /* Test the shader path */
2580     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2581         skip("Vertex shaders not supported\n");
2582         goto out;
2583     }
2584     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2585     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2586     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2587     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2588
2589     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2590
2591     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2592     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2593     hr = IDirect3DDevice9_SetVertexShader(device, shader);
2594     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2595
2596     hr = IDirect3DDevice9_BeginScene(device);
2597     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2598     if(hr == D3D_OK)
2599     {
2600         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2601         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2602         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2603         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2604         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2605         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2606         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2607         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2608         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2609         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2610
2611         hr = IDirect3DDevice9_EndScene(device);
2612         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2613     }
2614
2615     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2616     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2617     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2618     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2619
2620     IDirect3DVertexDeclaration9_Release(decl);
2621     IDirect3DVertexShader9_Release(shader);
2622
2623     /* Z < 1.0 */
2624     color = getPixelColor(device, 28, 238);
2625     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2626
2627     /* 1.0 < z < 0.75 */
2628     color = getPixelColor(device, 31, 238);
2629     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2630     color = getPixelColor(device, 100, 238);
2631     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2632
2633     /* 0.75 < z < 0.0 */
2634     color = getPixelColor(device, 104, 238);
2635     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2636     color = getPixelColor(device, 318, 238);
2637     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2638
2639     /* 0.0 < z */
2640     color = getPixelColor(device, 321, 238);
2641     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2642
2643     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2644     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2645
2646     out:
2647     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2648     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2649     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2650     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2651     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2652     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2653 }
2654
2655 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2656 {
2657     D3DSURFACE_DESC desc;
2658     D3DLOCKED_RECT l;
2659     HRESULT hr;
2660     unsigned int x, y;
2661     DWORD *mem;
2662
2663     memset(&desc, 0, sizeof(desc));
2664     memset(&l, 0, sizeof(l));
2665     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2666     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2667     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2668     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2669     if(FAILED(hr)) return;
2670
2671     for(y = 0; y < desc.Height; y++)
2672     {
2673         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2674         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2675         {
2676             mem[x] = color;
2677         }
2678     }
2679     hr = IDirect3DSurface9_UnlockRect(surface);
2680     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2681 }
2682
2683 /* This tests a variety of possible StretchRect() situations */
2684 static void stretchrect_test(IDirect3DDevice9 *device)
2685 {
2686     HRESULT hr;
2687     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2688     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2689     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2690     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2691     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2692     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2693     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2694     IDirect3DSurface9 *orig_rt = NULL;
2695     IDirect3DSurface9 *backbuffer = NULL;
2696     DWORD color;
2697
2698     RECT src_rect64 = {0, 0, 64, 64};
2699     RECT src_rect64_flipy = {0, 64, 64, 0};
2700     RECT dst_rect64 = {0, 0, 64, 64};
2701     RECT dst_rect64_flipy = {0, 64, 64, 0};
2702
2703     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2704     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2705     if(!orig_rt) {
2706         goto out;
2707     }
2708
2709     /* Create our temporary surfaces in system memory */
2710     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2711     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2712     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2713     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2714
2715     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2716     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2717     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2718     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2719     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2720     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2721     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2722
2723     /* Create render target surfaces */
2724     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2725     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2726     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2727     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2728     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2729     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2730     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2731     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2732
2733     /* Create render target textures */
2734     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2735     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2736     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2737     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2738     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2739     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2740     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2741     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2742     if (tex_rt32) {
2743         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2744         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2745     }
2746     if (tex_rt64) {
2747         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2748         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2749     }
2750     if (tex_rt_dest64) {
2751         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2752         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2753     }
2754     if (tex_rt_dest64) {
2755         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2756         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2757     }
2758
2759     /* Create regular textures in D3DPOOL_DEFAULT */
2760     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2761     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2762     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2763     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2764     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2765     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2766     if (tex32) {
2767         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2768         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2769     }
2770     if (tex64) {
2771         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2772         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2773     }
2774     if (tex_dest64) {
2775         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2776         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2777     }
2778
2779     /*********************************************************************
2780      * Tests for when the source parameter is an offscreen plain surface *
2781      *********************************************************************/
2782
2783     /* Fill the offscreen 64x64 surface with green */
2784     if (surf_offscreen64)
2785         fill_surface(surf_offscreen64, 0xff00ff00);
2786
2787     /* offscreenplain ==> offscreenplain, same size */
2788     if(surf_offscreen64 && surf_offscreen_dest64) {
2789         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2790         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2791
2792         if (hr == D3D_OK) {
2793             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2794             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2795         }
2796
2797         /* Blit without scaling */
2798         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2799         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2800
2801         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2802         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2803         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2804
2805         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2806         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2807         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2808     }
2809
2810     /* offscreenplain ==> rendertarget texture, same size */
2811     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2812         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2813         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2814
2815         /* We can't lock rendertarget textures, so copy to our temp surface first */
2816         if (hr == D3D_OK) {
2817             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2818             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2819         }
2820
2821         if (hr == D3D_OK) {
2822             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2823             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2824         }
2825
2826         /* Blit without scaling */
2827         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2828         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2829
2830         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2831         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2832         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2833
2834         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2835         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2836         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2837     }
2838
2839     /* offscreenplain ==> rendertarget surface, same size */
2840     if(surf_offscreen64 && surf_rt_dest64) {
2841         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2842         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2843
2844         if (hr == D3D_OK) {
2845             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2846             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2847         }
2848
2849         /* Blit without scaling */
2850         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2851         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2852
2853         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2854         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2855         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2856
2857         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2858         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2859         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2860     }
2861
2862     /* offscreenplain ==> texture, same size (should fail) */
2863     if(surf_offscreen64 && surf_tex_dest64) {
2864         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2865         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2866     }
2867
2868     /* Fill the smaller offscreen surface with red */
2869     fill_surface(surf_offscreen32, 0xffff0000);
2870
2871     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2872     if(surf_offscreen32 && surf_offscreen64) {
2873         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2874         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2875     }
2876
2877     /* offscreenplain ==> rendertarget texture, scaling */
2878     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2879         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2880         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2881
2882         /* We can't lock rendertarget textures, so copy to our temp surface first */
2883         if (hr == D3D_OK) {
2884             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2885             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2886         }
2887
2888         if (hr == D3D_OK) {
2889             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2890             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2891         }
2892     }
2893
2894     /* offscreenplain ==> rendertarget surface, scaling */
2895     if(surf_offscreen32 && surf_rt_dest64) {
2896         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2897         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2898
2899         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2900         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2901     }
2902
2903     /* offscreenplain ==> texture, scaling (should fail) */
2904     if(surf_offscreen32 && surf_tex_dest64) {
2905         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2906         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2907     }
2908
2909     /************************************************************
2910      * Tests for when the source parameter is a regular texture *
2911      ************************************************************/
2912
2913     /* Fill the surface of the regular texture with blue */
2914     if (surf_tex64 && surf_temp64) {
2915         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2916         fill_surface(surf_temp64, 0xff0000ff);
2917         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2918         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2919     }
2920
2921     /* texture ==> offscreenplain, same size */
2922     if(surf_tex64 && surf_offscreen64) {
2923         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2924         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2925     }
2926
2927     /* texture ==> rendertarget texture, same size */
2928     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2929         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2930         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2931
2932         /* We can't lock rendertarget textures, so copy to our temp surface first */
2933         if (hr == D3D_OK) {
2934             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2935             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2936         }
2937
2938         if (hr == D3D_OK) {
2939             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2940             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2941         }
2942
2943         /* Blit without scaling */
2944         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2945         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2946
2947         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2948         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2949         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2950
2951         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2952         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2953         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2954     }
2955
2956     /* texture ==> rendertarget surface, same size */
2957     if(surf_tex64 && surf_rt_dest64) {
2958         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2959         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2960
2961         if (hr == D3D_OK) {
2962             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2963             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2964         }
2965
2966         /* Blit without scaling */
2967         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2968         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2969
2970         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2971         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2972         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2973
2974         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2975         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2976         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2977     }
2978
2979     /* texture ==> texture, same size (should fail) */
2980     if(surf_tex64 && surf_tex_dest64) {
2981         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2982         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2983     }
2984
2985     /* Fill the surface of the smaller regular texture with red */
2986     if (surf_tex32 && surf_temp32) {
2987         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2988         fill_surface(surf_temp32, 0xffff0000);
2989         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2990         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2991     }
2992
2993     /* texture ==> offscreenplain, scaling (should fail) */
2994     if(surf_tex32 && surf_offscreen64) {
2995         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2996         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2997     }
2998
2999     /* texture ==> rendertarget texture, scaling */
3000     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
3001         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
3002         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3003
3004         /* We can't lock rendertarget textures, so copy to our temp surface first */
3005         if (hr == D3D_OK) {
3006             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3007             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3008         }
3009
3010         if (hr == D3D_OK) {
3011             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3012             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3013         }
3014     }
3015
3016     /* texture ==> rendertarget surface, scaling */
3017     if(surf_tex32 && surf_rt_dest64) {
3018         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
3019         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3020
3021         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3022         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3023     }
3024
3025     /* texture ==> texture, scaling (should fail) */
3026     if(surf_tex32 && surf_tex_dest64) {
3027         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
3028         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3029     }
3030
3031     /*****************************************************************
3032      * Tests for when the source parameter is a rendertarget texture *
3033      *****************************************************************/
3034
3035     /* Fill the surface of the rendertarget texture with white */
3036     if (surf_tex_rt64 && surf_temp64) {
3037         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
3038         fill_surface(surf_temp64, 0xffffffff);
3039         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
3040         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3041     }
3042
3043     /* rendertarget texture ==> offscreenplain, same size */
3044     if(surf_tex_rt64 && surf_offscreen64) {
3045         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
3046         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3047     }
3048
3049     /* rendertarget texture ==> rendertarget texture, same size */
3050     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3051         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3052         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3053
3054         /* We can't lock rendertarget textures, so copy to our temp surface first */
3055         if (hr == D3D_OK) {
3056             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3057             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3058         }
3059
3060         if (hr == D3D_OK) {
3061             color = getPixelColorFromSurface(surf_temp64, 32, 32);
3062             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
3063         }
3064
3065         /* Blit without scaling */
3066         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3067         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3068
3069         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3070         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3071         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3072
3073         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3074         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3075         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3076     }
3077
3078     /* rendertarget texture ==> rendertarget surface, same size */
3079     if(surf_tex_rt64 && surf_rt_dest64) {
3080         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
3081         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3082
3083         if (hr == D3D_OK) {
3084             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3085             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
3086         }
3087
3088         /* Blit without scaling */
3089         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3090         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3091
3092         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3093         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
3094         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3095
3096         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3097         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3098         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3099     }
3100
3101     /* rendertarget texture ==> texture, same size (should fail) */
3102     if(surf_tex_rt64 && surf_tex_dest64) {
3103         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
3104         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3105     }
3106
3107     /* Fill the surface of the smaller rendertarget texture with red */
3108     if (surf_tex_rt32 && surf_temp32) {
3109         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
3110         fill_surface(surf_temp32, 0xffff0000);
3111         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3112         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3113     }
3114
3115     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
3116     if(surf_tex_rt32 && surf_offscreen64) {
3117         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
3118         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3119     }
3120
3121     /* rendertarget texture ==> rendertarget texture, scaling */
3122     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3123         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3124         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3125
3126         /* We can't lock rendertarget textures, so copy to our temp surface first */
3127         if (hr == D3D_OK) {
3128             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3129             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3130         }
3131
3132         if (hr == D3D_OK) {
3133             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3134             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3135         }
3136     }
3137
3138     /* rendertarget texture ==> rendertarget surface, scaling */
3139     if(surf_tex_rt32 && surf_rt_dest64) {
3140         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
3141         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3142
3143         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3144         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3145     }
3146
3147     /* rendertarget texture ==> texture, scaling (should fail) */
3148     if(surf_tex_rt32 && surf_tex_dest64) {
3149         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
3150         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3151     }
3152
3153     /*****************************************************************
3154      * Tests for when the source parameter is a rendertarget surface *
3155      *****************************************************************/
3156
3157     /* Fill the surface of the rendertarget surface with black */
3158     if (surf_rt64)
3159         fill_surface(surf_rt64, 0xff000000);
3160
3161     /* rendertarget texture ==> offscreenplain, same size */
3162     if(surf_rt64 && surf_offscreen64) {
3163         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
3164         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3165     }
3166
3167     /* rendertarget surface ==> rendertarget texture, same size */
3168     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3169         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3170         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3171
3172         /* We can't lock rendertarget textures, so copy to our temp surface first */
3173         if (hr == D3D_OK) {
3174             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3175             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3176         }
3177
3178         if (hr == D3D_OK) {
3179             color = getPixelColorFromSurface(surf_temp64, 32, 32);
3180             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3181         }
3182
3183         /* Blit without scaling */
3184         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3185         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3186
3187         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3188         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3189         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3190
3191         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3192         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3193         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3194     }
3195
3196     /* rendertarget surface ==> rendertarget surface, same size */
3197     if(surf_rt64 && surf_rt_dest64) {
3198         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
3199         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3200
3201         if (hr == D3D_OK) {
3202             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3203             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3204         }
3205
3206         /* Blit without scaling */
3207         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3208         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3209
3210         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3211         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
3212         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3213
3214         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3215         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3216         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3217     }
3218
3219     /* rendertarget surface ==> texture, same size (should fail) */
3220     if(surf_rt64 && surf_tex_dest64) {
3221         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
3222         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3223     }
3224
3225     /* Fill the surface of the smaller rendertarget texture with red */
3226     if (surf_rt32)
3227         fill_surface(surf_rt32, 0xffff0000);
3228
3229     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
3230     if(surf_rt32 && surf_offscreen64) {
3231         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
3232         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3233     }
3234
3235     /* rendertarget surface ==> rendertarget texture, scaling */
3236     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3237         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3238         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3239
3240         /* We can't lock rendertarget textures, so copy to our temp surface first */
3241         if (hr == D3D_OK) {
3242             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3243             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3244         }
3245
3246         if (hr == D3D_OK) {
3247             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3248             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3249         }
3250     }
3251
3252     /* rendertarget surface ==> rendertarget surface, scaling */
3253     if(surf_rt32 && surf_rt_dest64) {
3254         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
3255         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3256
3257         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3258         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3259     }
3260
3261     /* rendertarget surface ==> texture, scaling (should fail) */
3262     if(surf_rt32 && surf_tex_dest64) {
3263         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
3264         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3265     }
3266
3267     /* backbuffer ==> surface tests (no scaling) */
3268     if(backbuffer && surf_tex_rt_dest640_480)
3269     {
3270         RECT src_rect = {0, 0, 640, 480};
3271         RECT src_rect_flipy = {0, 480, 640, 0};
3272         RECT dst_rect = {0, 0, 640, 480};
3273         RECT dst_rect_flipy = {0, 480, 640, 0};
3274
3275         /* Blit with NULL rectangles */
3276         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
3277         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
3278
3279         /* Blit without scaling */
3280         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
3281         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3282
3283         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3284         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
3285         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3286
3287         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3288         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
3289         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3290     }
3291
3292     /* TODO: Test format conversions */
3293
3294
3295 out:
3296     /* Clean up */
3297     if (backbuffer)
3298         IDirect3DSurface9_Release(backbuffer);
3299     if (surf_rt32)
3300         IDirect3DSurface9_Release(surf_rt32);
3301     if (surf_rt64)
3302         IDirect3DSurface9_Release(surf_rt64);
3303     if (surf_rt_dest64)
3304         IDirect3DSurface9_Release(surf_rt_dest64);
3305     if (surf_temp32)
3306         IDirect3DSurface9_Release(surf_temp32);
3307     if (surf_temp64)
3308         IDirect3DSurface9_Release(surf_temp64);
3309     if (surf_offscreen32)
3310         IDirect3DSurface9_Release(surf_offscreen32);
3311     if (surf_offscreen64)
3312         IDirect3DSurface9_Release(surf_offscreen64);
3313     if (surf_offscreen_dest64)
3314         IDirect3DSurface9_Release(surf_offscreen_dest64);
3315
3316     if (tex_rt32) {
3317         if (surf_tex_rt32)
3318             IDirect3DSurface9_Release(surf_tex_rt32);
3319         IDirect3DTexture9_Release(tex_rt32);
3320     }
3321     if (tex_rt64) {
3322         if (surf_tex_rt64)
3323             IDirect3DSurface9_Release(surf_tex_rt64);
3324         IDirect3DTexture9_Release(tex_rt64);
3325     }
3326     if (tex_rt_dest64) {
3327         if (surf_tex_rt_dest64)
3328             IDirect3DSurface9_Release(surf_tex_rt_dest64);
3329         IDirect3DTexture9_Release(tex_rt_dest64);
3330     }
3331     if (tex_rt_dest640_480) {
3332         if (surf_tex_rt_dest640_480)
3333             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
3334         IDirect3DTexture9_Release(tex_rt_dest640_480);
3335     }
3336     if (tex32) {
3337         if (surf_tex32)
3338             IDirect3DSurface9_Release(surf_tex32);
3339         IDirect3DTexture9_Release(tex32);
3340     }
3341     if (tex64) {
3342         if (surf_tex64)
3343             IDirect3DSurface9_Release(surf_tex64);
3344         IDirect3DTexture9_Release(tex64);
3345     }
3346     if (tex_dest64) {
3347         if (surf_tex_dest64)
3348             IDirect3DSurface9_Release(surf_tex_dest64);
3349         IDirect3DTexture9_Release(tex_dest64);
3350     }
3351
3352     if (orig_rt) {
3353         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3354         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3355         IDirect3DSurface9_Release(orig_rt);
3356     }
3357 }
3358
3359 static void maxmip_test(IDirect3DDevice9 *device)
3360 {
3361     IDirect3DTexture9 *texture = NULL;
3362     IDirect3DSurface9 *surface = NULL;
3363     HRESULT hr;
3364     DWORD color;
3365     static const struct
3366     {
3367         struct
3368         {
3369             float x, y, z;
3370             float s, t;
3371         }
3372         v[4];
3373     }
3374     quads[] =
3375     {
3376         {{
3377             {-1.0, -1.0,  0.0,  0.0,  0.0},
3378             {-1.0,  0.0,  0.0,  0.0,  1.0},
3379             { 0.0, -1.0,  0.0,  1.0,  0.0},
3380             { 0.0,  0.0,  0.0,  1.0,  1.0},
3381         }},
3382         {{
3383             { 0.0, -1.0,  0.0,  0.0,  0.0},
3384             { 0.0,  0.0,  0.0,  0.0,  1.0},
3385             { 1.0, -1.0,  0.0,  1.0,  0.0},
3386             { 1.0,  0.0,  0.0,  1.0,  1.0},
3387         }},
3388         {{
3389             { 0.0,  0.0,  0.0,  0.0,  0.0},
3390             { 0.0,  1.0,  0.0,  0.0,  1.0},
3391             { 1.0,  0.0,  0.0,  1.0,  0.0},
3392             { 1.0,  1.0,  0.0,  1.0,  1.0},
3393         }},
3394         {{
3395             {-1.0,  0.0,  0.0,  0.0,  0.0},
3396             {-1.0,  1.0,  0.0,  0.0,  1.0},
3397             { 0.0,  0.0,  0.0,  1.0,  0.0},
3398             { 0.0,  1.0,  0.0,  1.0,  1.0},
3399         }},
3400     };
3401
3402     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3403                                         &texture, NULL);
3404     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3405     if(!texture)
3406     {
3407         skip("Failed to create test texture\n");
3408         return;
3409     }
3410
3411     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3412     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3413     fill_surface(surface, 0xffff0000);
3414     IDirect3DSurface9_Release(surface);
3415     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3416     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3417     fill_surface(surface, 0xff00ff00);
3418     IDirect3DSurface9_Release(surface);
3419     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3420     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3421     fill_surface(surface, 0xff0000ff);
3422     IDirect3DSurface9_Release(surface);
3423
3424     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3425     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3426     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3427     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3428
3429     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3430     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3431
3432     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3433     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3434
3435     hr = IDirect3DDevice9_BeginScene(device);
3436     if(SUCCEEDED(hr))
3437     {
3438         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3439         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3440         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3441         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3442
3443         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3444         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3445         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3446         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3447
3448         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3449         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3450         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3451         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3452
3453         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3454         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3455         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3456         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3457         hr = IDirect3DDevice9_EndScene(device);
3458         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3459     }
3460
3461     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3462     color = getPixelColor(device, 160, 360);
3463     ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3464     color = getPixelColor(device, 480, 360);
3465     ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3466     color = getPixelColor(device, 480, 120);
3467     ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3468     color = getPixelColor(device, 160, 120);
3469     ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3470     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3471     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3472
3473     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3474     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3475
3476     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3477     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3478
3479     hr = IDirect3DDevice9_BeginScene(device);
3480     if(SUCCEEDED(hr))
3481     {
3482         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3483         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3484         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3485         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3486
3487         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3488         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3489         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3490         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3491
3492         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3493         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3494         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3495         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3496
3497         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3498         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3499         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3500         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3501         hr = IDirect3DDevice9_EndScene(device);
3502         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3503     }
3504
3505     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3506      * level 3 (> levels in texture) samples from the highest level in the
3507      * texture (level 2). */
3508     color = getPixelColor(device, 160, 360);
3509     ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3510     color = getPixelColor(device, 480, 360);
3511     ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3512     color = getPixelColor(device, 480, 120);
3513     ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3514     color = getPixelColor(device, 160, 120);
3515     ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3516     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3517     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3518
3519     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3520     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3521
3522     hr = IDirect3DDevice9_BeginScene(device);
3523     if(SUCCEEDED(hr))
3524     {
3525         DWORD ret;
3526
3527         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3528         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3529         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3530         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3531         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3532         ret = IDirect3DTexture9_SetLOD(texture, 1);
3533         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3534         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3535         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3536
3537         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3538         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3539         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3540         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3541         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3542         ret = IDirect3DTexture9_SetLOD(texture, 2);
3543         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3544         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3545         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3546
3547         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3548         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3549         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3550         ret = IDirect3DTexture9_SetLOD(texture, 1);
3551         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3552         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3553         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3554
3555         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3556         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3557         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3558         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3559         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3560         ret = IDirect3DTexture9_SetLOD(texture, 1);
3561         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3562         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3563         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3564         hr = IDirect3DDevice9_EndScene(device);
3565         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3566     }
3567
3568     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3569      * level 3 (> levels in texture) samples from the highest level in the
3570      * texture (level 2). */
3571     color = getPixelColor(device, 160, 360);
3572     ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3573     color = getPixelColor(device, 480, 360);
3574     ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3575     color = getPixelColor(device, 480, 120);
3576     ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3577     color = getPixelColor(device, 160, 120);
3578     ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3579
3580     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3581     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3582
3583     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3584     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3585     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3586     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3587     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3588     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3589     IDirect3DTexture9_Release(texture);
3590 }
3591
3592 static void release_buffer_test(IDirect3DDevice9 *device)
3593 {
3594     IDirect3DVertexBuffer9 *vb = NULL;
3595     IDirect3DIndexBuffer9 *ib = NULL;
3596     HRESULT hr;
3597     BYTE *data;
3598     LONG ref;
3599
3600     static const struct vertex quad[] = {
3601         {-1.0,      -1.0,       0.1,        0xffff0000},
3602         {-1.0,       1.0,       0.1,        0xffff0000},
3603         { 1.0,       1.0,       0.1,        0xffff0000},
3604
3605         {-1.0,      -1.0,       0.1,        0xff00ff00},
3606         {-1.0,       1.0,       0.1,        0xff00ff00},
3607         { 1.0,       1.0,       0.1,        0xff00ff00}
3608     };
3609     short indices[] = {3, 4, 5};
3610
3611     /* Index and vertex buffers should always be creatable */
3612     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3613                                               D3DPOOL_MANAGED, &vb, NULL);
3614     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3615     if(!vb) {
3616         skip("Failed to create a vertex buffer\n");
3617         return;
3618     }
3619     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3620     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3621     if(!ib) {
3622         skip("Failed to create an index buffer\n");
3623         return;
3624     }
3625
3626     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3627     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3628     memcpy(data, quad, sizeof(quad));
3629     hr = IDirect3DVertexBuffer9_Unlock(vb);
3630     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3631
3632     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3633     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3634     memcpy(data, indices, sizeof(indices));
3635     hr = IDirect3DIndexBuffer9_Unlock(ib);
3636     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3637
3638     hr = IDirect3DDevice9_SetIndices(device, ib);
3639     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3640     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3641     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3642     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3643     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3644
3645     /* Now destroy the bound index buffer and draw again */
3646     ref = IDirect3DIndexBuffer9_Release(ib);
3647     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3648
3649     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3650     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3651
3652     hr = IDirect3DDevice9_BeginScene(device);
3653     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3654     if(SUCCEEDED(hr))
3655     {
3656         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3657          * making assumptions about the indices or vertices
3658          */
3659         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3660         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3661         hr = IDirect3DDevice9_EndScene(device);
3662         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3663     }
3664
3665     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3666     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3667
3668     hr = IDirect3DDevice9_SetIndices(device, NULL);
3669     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3670     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3671     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3672
3673     /* Index buffer was already destroyed as part of the test */
3674     IDirect3DVertexBuffer9_Release(vb);
3675 }
3676
3677 static void float_texture_test(IDirect3DDevice9 *device)
3678 {
3679     IDirect3D9 *d3d = NULL;
3680     HRESULT hr;
3681     IDirect3DTexture9 *texture = NULL;
3682     D3DLOCKED_RECT lr;
3683     float *data;
3684     DWORD color;
3685     float quad[] = {
3686         -1.0,      -1.0,       0.1,     0.0,    0.0,
3687         -1.0,       1.0,       0.1,     0.0,    1.0,
3688          1.0,      -1.0,       0.1,     1.0,    0.0,
3689          1.0,       1.0,       0.1,     1.0,    1.0,
3690     };
3691
3692     memset(&lr, 0, sizeof(lr));
3693     IDirect3DDevice9_GetDirect3D(device, &d3d);
3694     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3695                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3696         skip("D3DFMT_R32F textures not supported\n");
3697         goto out;
3698     }
3699
3700     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3701                                         D3DPOOL_MANAGED, &texture, NULL);
3702     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3703     if(!texture) {
3704         skip("Failed to create R32F texture\n");
3705         goto out;
3706     }
3707
3708     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3709     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3710     data = lr.pBits;
3711     *data = 0.0;
3712     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3713     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3714
3715     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3716     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3717
3718     hr = IDirect3DDevice9_BeginScene(device);
3719     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3720     if(SUCCEEDED(hr))
3721     {
3722         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3723         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3724
3725         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3726         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3727
3728         hr = IDirect3DDevice9_EndScene(device);
3729         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3730     }
3731     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3732     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3733
3734     color = getPixelColor(device, 240, 320);
3735     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3736
3737     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3738     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3739
3740 out:
3741     if(texture) IDirect3DTexture9_Release(texture);
3742     IDirect3D9_Release(d3d);
3743 }
3744
3745 static void g16r16_texture_test(IDirect3DDevice9 *device)
3746 {
3747     IDirect3D9 *d3d = NULL;
3748     HRESULT hr;
3749     IDirect3DTexture9 *texture = NULL;
3750     D3DLOCKED_RECT lr;
3751     DWORD *data;
3752     DWORD color;
3753     float quad[] = {
3754        -1.0,      -1.0,       0.1,     0.0,    0.0,
3755        -1.0,       1.0,       0.1,     0.0,    1.0,
3756         1.0,      -1.0,       0.1,     1.0,    0.0,
3757         1.0,       1.0,       0.1,     1.0,    1.0,
3758     };
3759
3760     memset(&lr, 0, sizeof(lr));
3761     IDirect3DDevice9_GetDirect3D(device, &d3d);
3762     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3763        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3764            skip("D3DFMT_G16R16 textures not supported\n");
3765            goto out;
3766     }
3767
3768     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3769                                         D3DPOOL_MANAGED, &texture, NULL);
3770     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3771     if(!texture) {
3772         skip("Failed to create D3DFMT_G16R16 texture\n");
3773         goto out;
3774     }
3775
3776     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3777     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3778     data = lr.pBits;
3779     *data = 0x0f00f000;
3780     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3781     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3782
3783     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3784     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3785
3786     hr = IDirect3DDevice9_BeginScene(device);
3787     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3788     if(SUCCEEDED(hr))
3789     {
3790         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3791         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3792
3793         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3794         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3795
3796         hr = IDirect3DDevice9_EndScene(device);
3797         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3798     }
3799     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3800     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3801
3802     color = getPixelColor(device, 240, 320);
3803     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3804        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3805
3806     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3807     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3808
3809 out:
3810     if(texture) IDirect3DTexture9_Release(texture);
3811     IDirect3D9_Release(d3d);
3812 }
3813
3814 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
3815 {
3816     LONG x_coords[2][2] =
3817     {
3818         {r.left - 1, r.left + 1},
3819         {r.right + 1, r.right - 1},
3820     };
3821     LONG y_coords[2][2] =
3822     {
3823         {r.top - 1, r.top + 1},
3824         {r.bottom + 1, r.bottom - 1}
3825     };
3826     unsigned int i, j, x_side, y_side;
3827
3828     for (i = 0; i < 2; ++i)
3829     {
3830         for (j = 0; j < 2; ++j)
3831         {
3832             for (x_side = 0; x_side < 2; ++x_side)
3833             {
3834                 for (y_side = 0; y_side < 2; ++y_side)
3835                 {
3836                     unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
3837                     DWORD color;
3838                     DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
3839
3840                     color = getPixelColor(device, x, y);
3841                     ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
3842                             message, x, y, color, expected);
3843                 }
3844             }
3845         }
3846     }
3847 }
3848
3849 struct projected_textures_test_run
3850 {
3851     const char *message;
3852     DWORD flags;
3853     IDirect3DVertexDeclaration9 *decl;
3854     BOOL vs, ps;
3855     RECT rect;
3856 };
3857
3858 static void projected_textures_test(IDirect3DDevice9 *device,
3859         struct projected_textures_test_run tests[4])
3860 {
3861     unsigned int i;
3862
3863     static const DWORD vertex_shader[] =
3864     {
3865         0xfffe0101,                                     /* vs_1_1           */
3866         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
3867         0x0000001f, 0x80000005, 0x900f0001,             /* dcl_texcoord0 v1 */
3868         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
3869         0x00000001, 0xe00f0000, 0x90e40001,             /* mov oT0, v1      */
3870         0x0000ffff                                      /* end              */
3871     };
3872     static const DWORD pixel_shader[] =
3873     {
3874         0xffff0103,                                     /* ps_1_3           */
3875         0x00000042, 0xb00f0000,                         /* tex t0           */
3876         0x00000001, 0x800f0000, 0xb0e40000,             /* mov r0, t0       */
3877         0x0000ffff                                      /* end              */
3878     };
3879     IDirect3DVertexShader9 *vs = NULL;
3880     IDirect3DPixelShader9 *ps = NULL;
3881     HRESULT hr;
3882
3883     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
3884     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
3885     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
3886     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3887
3888     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
3889     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3890
3891     hr = IDirect3DDevice9_BeginScene(device);
3892     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3893     if (FAILED(hr))
3894         return;
3895
3896     for (i = 0; i < 4; ++i)
3897     {
3898         DWORD value = 0xdeadbeef;
3899         static const float proj_quads[] =
3900         {
3901             -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3902              0.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3903             -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3904              0.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3905
3906              0.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3907              1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3908              0.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3909              1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3910
3911             -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3912              0.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3913             -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3914              0.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3915
3916              0.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3917              1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3918              0.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3919              1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3920         };
3921
3922         if (tests[i].vs)
3923             hr = IDirect3DDevice9_SetVertexShader(device, vs);
3924         else
3925             hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3926         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
3927         if (tests[i].ps)
3928             hr = IDirect3DDevice9_SetPixelShader(device, ps);
3929         else
3930             hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3931         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3932
3933         hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
3934         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3935
3936         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
3937         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3938         hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
3939         ok(SUCCEEDED(hr) && value == tests[i].flags,
3940                 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
3941
3942         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
3943                 &proj_quads[i * 4 * 7], 7 * sizeof(float));
3944         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3945     }
3946
3947     hr = IDirect3DDevice9_EndScene(device);
3948     ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3949
3950     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3951     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3952     IDirect3DVertexShader9_Release(vs);
3953     IDirect3DPixelShader9_Release(ps);
3954
3955     for (i = 0; i < 4; ++i)
3956         check_rect(device, tests[i].rect, tests[i].message);
3957
3958     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3959     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3960 }
3961
3962 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3963 {
3964     HRESULT hr;
3965     IDirect3D9 *d3d;
3966     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3967     D3DCAPS9 caps;
3968     IDirect3DTexture9 *texture = NULL;
3969     IDirect3DVolumeTexture9 *volume = NULL;
3970     unsigned int x, y, z;
3971     D3DLOCKED_RECT lr;
3972     D3DLOCKED_BOX lb;
3973     DWORD color;
3974     UINT w, h;
3975     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
3976     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3977                            0.0, 1.0, 0.0, 0.0,
3978                            0.0, 0.0, 1.0, 0.0,
3979                            0.0, 0.0, 0.0, 1.0};
3980     static const D3DVERTEXELEMENT9 decl_elements[] = {
3981         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3982         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3983         D3DDECL_END()
3984     };
3985     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3986         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3987         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3988         D3DDECL_END()
3989     };
3990     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3991         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3992         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3993         D3DDECL_END()
3994     };
3995     static const D3DVERTEXELEMENT9 decl_elements4[] = {
3996         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3997         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3998         D3DDECL_END()
3999     };
4000     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
4001                                                  0x00, 0xff, 0x00, 0x00,
4002                                                  0x00, 0x00, 0x00, 0x00,
4003                                                  0x00, 0x00, 0x00, 0x00};
4004
4005     memset(&lr, 0, sizeof(lr));
4006     memset(&lb, 0, sizeof(lb));
4007     IDirect3DDevice9_GetDirect3D(device, &d3d);
4008     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
4009                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
4010         fmt = D3DFMT_A16B16G16R16;
4011     }
4012     IDirect3D9_Release(d3d);
4013
4014     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4015     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4016     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4017     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4018     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
4019     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4020     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
4021     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4022     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
4023     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
4024     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
4025     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
4026     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
4027     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
4028     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4029     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
4030     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
4031     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
4032     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
4033     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
4034     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
4035     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
4036     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4037     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
4038     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4039     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4040
4041     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4042     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
4043     w = min(1024, caps.MaxTextureWidth);
4044     h = min(1024, caps.MaxTextureHeight);
4045     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
4046                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
4047     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4048     if(!texture) {
4049         skip("Failed to create the test texture\n");
4050         return;
4051     }
4052
4053     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
4054      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
4055      * 1.0 in red and green for the x and y coords
4056      */
4057     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4058     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
4059     for(y = 0; y < h; y++) {
4060         for(x = 0; x < w; x++) {
4061             double r_f = (double) y / (double) h;
4062             double g_f = (double) x / (double) w;
4063             if(fmt == D3DFMT_A16B16G16R16) {
4064                 unsigned short r, g;
4065                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
4066                 r = (unsigned short) (r_f * 65536.0);
4067                 g = (unsigned short) (g_f * 65536.0);
4068                 dst[0] = r;
4069                 dst[1] = g;
4070                 dst[2] = 0;
4071                 dst[3] = 65535;
4072             } else {
4073                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
4074                 unsigned char r = (unsigned char) (r_f * 255.0);
4075                 unsigned char g = (unsigned char) (g_f * 255.0);
4076                 dst[0] = 0;
4077                 dst[1] = g;
4078                 dst[2] = r;
4079                 dst[3] = 255;
4080             }
4081         }
4082     }
4083     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4084     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4085     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4086     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4087
4088     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4089     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4090     hr = IDirect3DDevice9_BeginScene(device);
4091     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4092     if(SUCCEEDED(hr))
4093     {
4094         float quad1[] = {
4095             -1.0,      -1.0,       0.1,     1.0,    1.0,
4096             -1.0,       0.0,       0.1,     1.0,    1.0,
4097              0.0,      -1.0,       0.1,     1.0,    1.0,
4098              0.0,       0.0,       0.1,     1.0,    1.0,
4099         };
4100         float quad2[] = {
4101             -1.0,       0.0,       0.1,     1.0,    1.0,
4102             -1.0,       1.0,       0.1,     1.0,    1.0,
4103              0.0,       0.0,       0.1,     1.0,    1.0,
4104              0.0,       1.0,       0.1,     1.0,    1.0,
4105         };
4106         float quad3[] = {
4107              0.0,       0.0,       0.1,     0.5,    0.5,
4108              0.0,       1.0,       0.1,     0.5,    0.5,
4109              1.0,       0.0,       0.1,     0.5,    0.5,
4110              1.0,       1.0,       0.1,     0.5,    0.5,
4111         };
4112         float quad4[] = {
4113              320,       480,       0.1,     1.0,    0.0,    1.0,
4114              320,       240,       0.1,     1.0,    0.0,    1.0,
4115              640,       480,       0.1,     1.0,    0.0,    1.0,
4116              640,       240,       0.1,     1.0,    0.0,    1.0,
4117         };
4118         float mat[16] = {0.0, 0.0, 0.0, 0.0,
4119                           0.0, 0.0, 0.0, 0.0,
4120                           0.0, 0.0, 0.0, 0.0,
4121                           0.0, 0.0, 0.0, 0.0};
4122
4123         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4124         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4125         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4126         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4127         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4128
4129         /* What happens with transforms enabled? */
4130         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4131         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4132         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4133         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4134
4135         /* What happens if 4 coords are used, but only 2 given ?*/
4136         mat[8] = 1.0;
4137         mat[13] = 1.0;
4138         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4139         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4140         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4141         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4142         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4143         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4144
4145         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4146          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4147          * due to the coords in the vertices. (turns out red, indeed)
4148          */
4149         memset(mat, 0, sizeof(mat));
4150         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4151         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4152         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4153         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4154         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4155         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4156         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4157         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4158
4159         hr = IDirect3DDevice9_EndScene(device);
4160         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4161     }
4162     color = getPixelColor(device, 160, 360);
4163     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
4164     color = getPixelColor(device, 160, 120);
4165     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4166     color = getPixelColor(device, 480, 120);
4167     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
4168     color = getPixelColor(device, 480, 360);
4169     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
4170     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4171     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4172
4173     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4174     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4175
4176     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4177     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4178     hr = IDirect3DDevice9_BeginScene(device);
4179     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4180     if(SUCCEEDED(hr))
4181     {
4182         float quad1[] = {
4183             -1.0,      -1.0,       0.1,     0.8,    0.2,
4184             -1.0,       0.0,       0.1,     0.8,    0.2,
4185              0.0,      -1.0,       0.1,     0.8,    0.2,
4186              0.0,       0.0,       0.1,     0.8,    0.2,
4187         };
4188         float quad2[] = {
4189             -1.0,       0.0,       0.1,     0.5,    1.0,
4190             -1.0,       1.0,       0.1,     0.5,    1.0,
4191              0.0,       0.0,       0.1,     0.5,    1.0,
4192              0.0,       1.0,       0.1,     0.5,    1.0,
4193         };
4194         float quad3[] = {
4195              0.0,       0.0,       0.1,     0.5,    1.0,
4196              0.0,       1.0,       0.1,     0.5,    1.0,
4197              1.0,       0.0,       0.1,     0.5,    1.0,
4198              1.0,       1.0,       0.1,     0.5,    1.0,
4199         };
4200         float quad4[] = {
4201              0.0,      -1.0,       0.1,     0.8,    0.2,
4202              0.0,       0.0,       0.1,     0.8,    0.2,
4203              1.0,      -1.0,       0.1,     0.8,    0.2,
4204              1.0,       0.0,       0.1,     0.8,    0.2,
4205         };
4206         float mat[16] = {0.0, 0.0, 0.0, 0.0,
4207                           0.0, 0.0, 0.0, 0.0,
4208                           0.0, 1.0, 0.0, 0.0,
4209                           0.0, 0.0, 0.0, 0.0};
4210
4211         /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
4212         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4213         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4214         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4215         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4216
4217         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4218         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4219
4220         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
4221          * it behaves like COUNT2 because normal textures require 2 coords. */
4222         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4223         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4224         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
4225         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4226
4227         /* Just to be sure, the same as quad2 above */
4228         memset(mat, 0, sizeof(mat));
4229         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4230         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4231         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4232         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4233         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4234         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4235
4236         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
4237          * used? And what happens to the first? */
4238         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4239         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4240         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4241         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4242
4243         hr = IDirect3DDevice9_EndScene(device);
4244         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4245     }
4246     color = getPixelColor(device, 160, 360);
4247     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
4248     color = getPixelColor(device, 160, 120);
4249     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4250     color = getPixelColor(device, 480, 120);
4251     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
4252        "quad 3 has color %08x, expected 0x00ff8000\n", color);
4253     color = getPixelColor(device, 480, 360);
4254     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
4255        "quad 4 has color %08x, expected 0x0033cc00\n", color);
4256     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4257     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4258
4259     IDirect3DTexture9_Release(texture);
4260
4261     /* Test projected textures, without any fancy matrices */
4262     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
4263     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4264     if (SUCCEEDED(hr))
4265     {
4266         struct projected_textures_test_run projected_tests_1[4] =
4267         {
4268             {
4269                 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
4270                 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
4271                 decl3,
4272                 FALSE, TRUE,
4273                 {120, 300, 240, 390},
4274             },
4275             {
4276                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
4277                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4278                 decl3,
4279                 FALSE, TRUE,
4280                 {400, 360, 480, 420},
4281             },
4282             /* Try with some invalid values */
4283             {
4284                 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
4285                 0xffffffff,
4286                 decl3,
4287                 FALSE, TRUE,
4288                 {120, 60, 240, 150}
4289             },
4290             {
4291                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
4292                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4293                 decl4,
4294                 FALSE, TRUE,
4295                 {340, 210, 360, 225},
4296             }
4297         };
4298         struct projected_textures_test_run projected_tests_2[4] =
4299         {
4300             {
4301                 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
4302                 D3DTTFF_PROJECTED,
4303                 decl3,
4304                 FALSE, TRUE,
4305                 {120, 300, 240, 390},
4306             },
4307             {
4308                 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
4309                 D3DTTFF_PROJECTED,
4310                 decl,
4311                 FALSE, TRUE,
4312                 {400, 360, 480, 420},
4313             },
4314             {
4315                 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
4316                 0xffffffff,
4317                 decl,
4318                 FALSE, TRUE,
4319                 {80, 120, 160, 180},
4320             },
4321             {
4322                 "D3DTTFF_COUNT1 (draws non-projected) - top right",
4323                 D3DTTFF_COUNT1,
4324                 decl4,
4325                 FALSE, TRUE,
4326                 {340, 210, 360, 225},
4327             }
4328         };
4329         struct projected_textures_test_run projected_tests_3[4] =
4330         {
4331             {
4332                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
4333                 D3DTTFF_PROJECTED,
4334                 decl3,
4335                 TRUE, FALSE,
4336                 {120, 300, 240, 390},
4337             },
4338             {
4339                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
4340                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4341                 decl3,
4342                 TRUE, TRUE,
4343                 {440, 300, 560, 390},
4344             },
4345             {
4346                 "0xffffffff (like COUNT4 | PROJECTED) - top left",
4347                 0xffffffff,
4348                 decl3,
4349                 TRUE, TRUE,
4350                 {120, 60, 240, 150},
4351             },
4352             {
4353                 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
4354                 D3DTTFF_PROJECTED,
4355                 decl3,
4356                 FALSE, FALSE,
4357                 {440, 60, 560, 150},
4358             },
4359         };
4360
4361         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4362         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4363
4364         hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4365         ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4366         for(x = 0; x < 4; x++) {
4367             memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
4368         }
4369         hr = IDirect3DTexture9_UnlockRect(texture, 0);
4370         ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4371         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4372         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4373
4374         projected_textures_test(device, projected_tests_1);
4375         projected_textures_test(device, projected_tests_2);
4376         projected_textures_test(device, projected_tests_3);
4377
4378         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4379         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4380         IDirect3DTexture9_Release(texture);
4381     }
4382
4383     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
4384     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4385     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
4386      * Thus watch out if sampling from texels between 0 and 1.
4387      */
4388     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
4389     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
4390        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
4391     if(!volume) {
4392         skip("Failed to create a volume texture\n");
4393         goto out;
4394     }
4395
4396     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
4397     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
4398     for(z = 0; z < 32; z++) {
4399         for(y = 0; y < 32; y++) {
4400             for(x = 0; x < 32; x++) {
4401                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
4402                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
4403                 float r_f = (float) x / 31.0;
4404                 float g_f = (float) y / 31.0;
4405                 float b_f = (float) z / 31.0;
4406
4407                 if(fmt == D3DFMT_A16B16G16R16) {
4408                     unsigned short *mem_s = mem;
4409                     mem_s[0]  = r_f * 65535.0;
4410                     mem_s[1]  = g_f * 65535.0;
4411                     mem_s[2]  = b_f * 65535.0;
4412                     mem_s[3]  = 65535;
4413                 } else {
4414                     unsigned char *mem_c = mem;
4415                     mem_c[0]  = b_f * 255.0;
4416                     mem_c[1]  = g_f * 255.0;
4417                     mem_c[2]  = r_f * 255.0;
4418                     mem_c[3]  = 255;
4419                 }
4420             }
4421         }
4422     }
4423     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
4424     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4425
4426     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
4427     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4428
4429     hr = IDirect3DDevice9_BeginScene(device);
4430     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4431     if(SUCCEEDED(hr))
4432     {
4433         float quad1[] = {
4434             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4435             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4436              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4437              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4438         };
4439         float quad2[] = {
4440             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4441             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
4442              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4443              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
4444         };
4445         float quad3[] = {
4446              0.0,       0.0,       0.1,     0.0,    0.0,
4447              0.0,       1.0,       0.1,     0.0,    0.0,
4448              1.0,       0.0,       0.1,     0.0,    0.0,
4449              1.0,       1.0,       0.1,     0.0,    0.0
4450         };
4451         float quad4[] = {
4452              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4453              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4454              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4455              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
4456         };
4457         float mat[16] = {1.0, 0.0, 0.0, 0.0,
4458                          0.0, 0.0, 1.0, 0.0,
4459                          0.0, 1.0, 0.0, 0.0,
4460                          0.0, 0.0, 0.0, 1.0};
4461         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4462         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4463
4464         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
4465          * values
4466          */
4467         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4468         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4469         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4470         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4471         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4472         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4473
4474         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
4475          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
4476          * otherwise the w will be missing(blue).
4477          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
4478          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
4479         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4480         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4481         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4482         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4483
4484         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
4485         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4486         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4487         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4488         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4489         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4490         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4491         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4492         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4493
4494         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4495          * disable. ATI extends it up to the amount of values needed for the volume texture
4496          */
4497         memset(mat, 0, sizeof(mat));
4498         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4499         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4500         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4501         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4502         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4503         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4504         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4505         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4506
4507         hr = IDirect3DDevice9_EndScene(device);
4508         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4509     }
4510
4511     color = getPixelColor(device, 160, 360);
4512     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4513     color = getPixelColor(device, 160, 120);
4514     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4515        "quad 2 has color %08x, expected 0x00ffff00\n", color);
4516     color = getPixelColor(device, 480, 120);
4517     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4518     color = getPixelColor(device, 480, 360);
4519     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4520
4521     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4522     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4523
4524     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4525     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4526     hr = IDirect3DDevice9_BeginScene(device);
4527     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4528     if(SUCCEEDED(hr))
4529     {
4530         float quad1[] = {
4531             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4532             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4533              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4534              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4535         };
4536         float quad2[] = {
4537             -1.0,       0.0,       0.1,
4538             -1.0,       1.0,       0.1,
4539              0.0,       0.0,       0.1,
4540              0.0,       1.0,       0.1,
4541         };
4542         float quad3[] = {
4543              0.0,       0.0,       0.1,     1.0,
4544              0.0,       1.0,       0.1,     1.0,
4545              1.0,       0.0,       0.1,     1.0,
4546              1.0,       1.0,       0.1,     1.0
4547         };
4548         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4549                            0.0, 0.0, 0.0, 0.0,
4550                            0.0, 0.0, 0.0, 0.0,
4551                            0.0, 1.0, 0.0, 0.0};
4552         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4553                            1.0, 0.0, 0.0, 0.0,
4554                            0.0, 1.0, 0.0, 0.0,
4555                            0.0, 0.0, 1.0, 0.0};
4556         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4557         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4558
4559         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4560          * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4561          * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4562          * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4563          * 4th *input* coordinate.
4564          */
4565         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4566         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4567         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4568         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4569         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4570         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4571
4572         /* None passed */
4573         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4574         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4575         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4576         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4577         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4578         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4579
4580         /* 4 used, 1 passed */
4581         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4582         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4583         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4584         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4585         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4586         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4587
4588         hr = IDirect3DDevice9_EndScene(device);
4589         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4590     }
4591     color = getPixelColor(device, 160, 360);
4592     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4593     color = getPixelColor(device, 160, 120);
4594     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4595     color = getPixelColor(device, 480, 120);
4596     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4597     /* Quad4: unused */
4598
4599     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4600     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4601
4602     IDirect3DVolumeTexture9_Release(volume);
4603
4604     out:
4605     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4606     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4607     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4608     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4609     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4610     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4611     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4612     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4613     IDirect3DVertexDeclaration9_Release(decl);
4614     IDirect3DVertexDeclaration9_Release(decl2);
4615     IDirect3DVertexDeclaration9_Release(decl3);
4616     IDirect3DVertexDeclaration9_Release(decl4);
4617 }
4618
4619 static void texdepth_test(IDirect3DDevice9 *device)
4620 {
4621     IDirect3DPixelShader9 *shader;
4622     HRESULT hr;
4623     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4624     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4625     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4626     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4627     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4628     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4629     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4630     DWORD shader_code[] = {
4631         0xffff0104,                                                                 /* ps_1_4               */
4632         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4633         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4634         0x0000fffd,                                                                 /* phase                */
4635         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4636         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4637         0x0000ffff                                                                  /* end                  */
4638     };
4639     DWORD color;
4640     float vertex[] = {
4641        -1.0,   -1.0,    0.0,
4642         1.0,   -1.0,    1.0,
4643        -1.0,    1.0,    0.0,
4644         1.0,    1.0,    1.0
4645     };
4646
4647     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4648     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4649
4650     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4651     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4652     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4653     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4654     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4655     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4656     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4657     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4658     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4659     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4660
4661     /* Fill the depth buffer with a gradient */
4662     hr = IDirect3DDevice9_BeginScene(device);
4663     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4664     if(SUCCEEDED(hr))
4665     {
4666         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4667         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4668         hr = IDirect3DDevice9_EndScene(device);
4669         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4670     }
4671
4672     /* Now perform the actual tests. Same geometry, but with the shader */
4673     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4674     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4675     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4676     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4677     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4678     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4679
4680     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4681     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4682     hr = IDirect3DDevice9_BeginScene(device);
4683     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4684     if(SUCCEEDED(hr))
4685     {
4686         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4687         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4688
4689         hr = IDirect3DDevice9_EndScene(device);
4690         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4691     }
4692
4693     color = getPixelColor(device, 158, 240);
4694     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4695     color = getPixelColor(device, 162, 240);
4696     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4697
4698     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4699     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4700
4701     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4702     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4703
4704     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4705     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4706     hr = IDirect3DDevice9_BeginScene(device);
4707     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4708     if(SUCCEEDED(hr))
4709     {
4710         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4711         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4712
4713         hr = IDirect3DDevice9_EndScene(device);
4714         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4715     }
4716
4717     color = getPixelColor(device, 318, 240);
4718     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4719     color = getPixelColor(device, 322, 240);
4720     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4721
4722     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4723     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4724
4725     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4726     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4727
4728     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4729     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4730     hr = IDirect3DDevice9_BeginScene(device);
4731     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4732     if(SUCCEEDED(hr))
4733     {
4734         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4735         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4736
4737         hr = IDirect3DDevice9_EndScene(device);
4738         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4739     }
4740
4741     color = getPixelColor(device, 1, 240);
4742     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4743
4744     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4745     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4746
4747     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4748     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4749
4750     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4751     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4752     hr = IDirect3DDevice9_BeginScene(device);
4753     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4754     if(SUCCEEDED(hr))
4755     {
4756         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4757         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4758
4759         hr = IDirect3DDevice9_EndScene(device);
4760         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4761     }
4762     color = getPixelColor(device, 318, 240);
4763     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4764     color = getPixelColor(device, 322, 240);
4765     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4766
4767     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4768     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4769
4770     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4771     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4772
4773     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4774     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4775     hr = IDirect3DDevice9_BeginScene(device);
4776     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4777     if(SUCCEEDED(hr))
4778     {
4779         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4780         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4781
4782         hr = IDirect3DDevice9_EndScene(device);
4783         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4784     }
4785
4786     color = getPixelColor(device, 1, 240);
4787     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4788
4789     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4790     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4791
4792     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4793     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4794
4795     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4796     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4797     hr = IDirect3DDevice9_BeginScene(device);
4798     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4799     if(SUCCEEDED(hr))
4800     {
4801         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4802         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4803
4804         hr = IDirect3DDevice9_EndScene(device);
4805         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4806     }
4807
4808     color = getPixelColor(device, 638, 240);
4809     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4810
4811     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4812     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4813
4814     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4815     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4816
4817     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4818     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4819     hr = IDirect3DDevice9_BeginScene(device);
4820     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4821     if(SUCCEEDED(hr))
4822     {
4823         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4824         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4825
4826         hr = IDirect3DDevice9_EndScene(device);
4827         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4828     }
4829
4830     color = getPixelColor(device, 638, 240);
4831     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4832
4833     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4834     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4835
4836     /* Cleanup */
4837     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4838     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4839     IDirect3DPixelShader9_Release(shader);
4840
4841     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4842     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4843     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4844     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4845 }
4846
4847 static void texkill_test(IDirect3DDevice9 *device)
4848 {
4849     IDirect3DPixelShader9 *shader;
4850     HRESULT hr;
4851     DWORD color;
4852
4853     const float vertex[] = {
4854     /*                          bottom  top    right    left */
4855         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4856          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4857         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4858          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4859     };
4860
4861     DWORD shader_code_11[] = {
4862     0xffff0101,                                                             /* ps_1_1                     */
4863     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4864     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4865     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4866     0x0000ffff                                                              /* end                        */
4867     };
4868     DWORD shader_code_20[] = {
4869     0xffff0200,                                                             /* ps_2_0                     */
4870     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4871     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4872     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4873     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4874     0x0000ffff                                                              /* end                        */
4875     };
4876
4877     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4878     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4879     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4880     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4881
4882     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4883     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4884     hr = IDirect3DDevice9_BeginScene(device);
4885     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4886     if(SUCCEEDED(hr))
4887     {
4888         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4889         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4890         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4891         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4892         hr = IDirect3DDevice9_EndScene(device);
4893         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4894     }
4895     color = getPixelColor(device, 63, 46);
4896     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4897     color = getPixelColor(device, 66, 46);
4898     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4899     color = getPixelColor(device, 63, 49);
4900     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4901     color = getPixelColor(device, 66, 49);
4902     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4903
4904     color = getPixelColor(device, 578, 46);
4905     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4906     color = getPixelColor(device, 575, 46);
4907     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4908     color = getPixelColor(device, 578, 49);
4909     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4910     color = getPixelColor(device, 575, 49);
4911     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4912
4913     color = getPixelColor(device, 63, 430);
4914     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4915     color = getPixelColor(device, 63, 433);
4916     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4917     color = getPixelColor(device, 66, 433);
4918     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4919     color = getPixelColor(device, 66, 430);
4920     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4921
4922     color = getPixelColor(device, 578, 430);
4923     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4924     color = getPixelColor(device, 578, 433);
4925     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4926     color = getPixelColor(device, 575, 433);
4927     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4928     color = getPixelColor(device, 575, 430);
4929     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4930
4931     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4932     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4933
4934     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4935     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4936     IDirect3DPixelShader9_Release(shader);
4937
4938     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4939     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4940     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4941     if(FAILED(hr)) {
4942         skip("Failed to create 2.0 test shader, most likely not supported\n");
4943         return;
4944     }
4945
4946     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4947     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4948     hr = IDirect3DDevice9_BeginScene(device);
4949     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4950     if(SUCCEEDED(hr))
4951     {
4952         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4953         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4954         hr = IDirect3DDevice9_EndScene(device);
4955         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4956     }
4957
4958     color = getPixelColor(device, 63, 46);
4959     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4960     color = getPixelColor(device, 66, 46);
4961     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4962     color = getPixelColor(device, 63, 49);
4963     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4964     color = getPixelColor(device, 66, 49);
4965     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4966
4967     color = getPixelColor(device, 578, 46);
4968     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4969     color = getPixelColor(device, 575, 46);
4970     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4971     color = getPixelColor(device, 578, 49);
4972     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4973     color = getPixelColor(device, 575, 49);
4974     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4975
4976     color = getPixelColor(device, 63, 430);
4977     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4978     color = getPixelColor(device, 63, 433);
4979     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4980     color = getPixelColor(device, 66, 433);
4981     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4982     color = getPixelColor(device, 66, 430);
4983     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4984
4985     color = getPixelColor(device, 578, 430);
4986     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4987     color = getPixelColor(device, 578, 433);
4988     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4989     color = getPixelColor(device, 575, 433);
4990     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4991     color = getPixelColor(device, 575, 430);
4992     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4993
4994     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4995     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4996
4997     /* Cleanup */
4998     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4999     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
5000     IDirect3DPixelShader9_Release(shader);
5001 }
5002
5003 static void x8l8v8u8_test(IDirect3DDevice9 *device)
5004 {
5005     IDirect3D9 *d3d9;
5006     HRESULT hr;
5007     IDirect3DTexture9 *texture;
5008     IDirect3DPixelShader9 *shader;
5009     IDirect3DPixelShader9 *shader2;
5010     D3DLOCKED_RECT lr;
5011     DWORD color;
5012     DWORD shader_code[] = {
5013         0xffff0101,                             /* ps_1_1       */
5014         0x00000042, 0xb00f0000,                 /* tex t0       */
5015         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
5016         0x0000ffff                              /* end          */
5017     };
5018     DWORD shader_code2[] = {
5019         0xffff0101,                             /* ps_1_1       */
5020         0x00000042, 0xb00f0000,                 /* tex t0       */
5021         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
5022         0x0000ffff                              /* end          */
5023     };
5024
5025     float quad[] = {
5026        -1.0,   -1.0,   0.1,     0.5,    0.5,
5027         1.0,   -1.0,   0.1,     0.5,    0.5,
5028        -1.0,    1.0,   0.1,     0.5,    0.5,
5029         1.0,    1.0,   0.1,     0.5,    0.5,
5030     };
5031
5032     memset(&lr, 0, sizeof(lr));
5033     IDirect3DDevice9_GetDirect3D(device, &d3d9);
5034     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5035                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
5036     IDirect3D9_Release(d3d9);
5037     if(FAILED(hr)) {
5038         skip("No D3DFMT_X8L8V8U8 support\n");
5039         return;
5040     };
5041
5042     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5043     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5044
5045     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
5046     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
5047     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5048     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
5049     *((DWORD *) lr.pBits) = 0x11ca3141;
5050     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5051     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
5052
5053     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5054     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5055     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
5056     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5057
5058     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5059     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5060     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5061     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5062     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5063     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5064
5065     hr = IDirect3DDevice9_BeginScene(device);
5066     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5067     if(SUCCEEDED(hr))
5068     {
5069         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5070         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5071
5072         hr = IDirect3DDevice9_EndScene(device);
5073         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5074     }
5075     color = getPixelColor(device, 578, 430);
5076     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
5077        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
5078     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5079     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5080
5081     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
5082     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5083     hr = IDirect3DDevice9_BeginScene(device);
5084     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5085     if(SUCCEEDED(hr))
5086     {
5087         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5088         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5089
5090         hr = IDirect3DDevice9_EndScene(device);
5091         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5092     }
5093     color = getPixelColor(device, 578, 430);
5094     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
5095     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5096     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5097
5098     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5099     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5100     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5101     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5102     IDirect3DPixelShader9_Release(shader);
5103     IDirect3DPixelShader9_Release(shader2);
5104     IDirect3DTexture9_Release(texture);
5105 }
5106
5107 static void autogen_mipmap_test(IDirect3DDevice9 *device)
5108 {
5109     HRESULT hr;
5110     IDirect3D9 *d3d;
5111     IDirect3DTexture9 *texture = NULL;
5112     IDirect3DSurface9 *surface;
5113     DWORD color;
5114     const RECT r1 = {256, 256, 512, 512};
5115     const RECT r2 = {512, 256, 768, 512};
5116     const RECT r3 = {256, 512, 512, 768};
5117     const RECT r4 = {512, 512, 768, 768};
5118     unsigned int x, y;
5119     D3DLOCKED_RECT lr;
5120     memset(&lr, 0, sizeof(lr));
5121
5122     IDirect3DDevice9_GetDirect3D(device, &d3d);
5123     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5124        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
5125         skip("No autogenmipmap support\n");
5126         IDirect3D9_Release(d3d);
5127         return;
5128     }
5129     IDirect3D9_Release(d3d);
5130
5131     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5132     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5133
5134     /* Make the mipmap big, so that a smaller mipmap is used
5135      */
5136     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5137                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5138     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5139
5140     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5141     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5142     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5143     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5144     for(y = 0; y < 1024; y++) {
5145         for(x = 0; x < 1024; x++) {
5146             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5147             POINT pt;
5148
5149             pt.x = x;
5150             pt.y = y;
5151             if(PtInRect(&r1, pt)) {
5152                 *dst = 0xffff0000;
5153             } else if(PtInRect(&r2, pt)) {
5154                 *dst = 0xff00ff00;
5155             } else if(PtInRect(&r3, pt)) {
5156                 *dst = 0xff0000ff;
5157             } else if(PtInRect(&r4, pt)) {
5158                 *dst = 0xff000000;
5159             } else {
5160                 *dst = 0xffffffff;
5161             }
5162         }
5163     }
5164     hr = IDirect3DSurface9_UnlockRect(surface);
5165     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5166     IDirect3DSurface9_Release(surface);
5167
5168     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5169     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5170     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5171     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5172
5173     hr = IDirect3DDevice9_BeginScene(device);
5174     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5175     if(SUCCEEDED(hr)) {
5176         const float quad[] =  {
5177            -0.5,   -0.5,    0.1,    0.0,    0.0,
5178            -0.5,    0.5,    0.1,    0.0,    1.0,
5179             0.5,   -0.5,    0.1,    1.0,    0.0,
5180             0.5,    0.5,    0.1,    1.0,    1.0
5181         };
5182
5183         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5184         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5185         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5186         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5187         hr = IDirect3DDevice9_EndScene(device);
5188         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5189     }
5190     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5191     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5192     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
5193     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5194     IDirect3DTexture9_Release(texture);
5195
5196     color = getPixelColor(device, 200, 200);
5197     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5198     color = getPixelColor(device, 280, 200);
5199     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5200     color = getPixelColor(device, 360, 200);
5201     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5202     color = getPixelColor(device, 440, 200);
5203     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5204     color = getPixelColor(device, 200, 270);
5205     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5206     color = getPixelColor(device, 280, 270);
5207     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5208     color = getPixelColor(device, 360, 270);
5209     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5210     color = getPixelColor(device, 440, 270);
5211     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5212     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5213     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5214 }
5215
5216 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
5217 {
5218     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5219     IDirect3DVertexDeclaration9 *decl;
5220     HRESULT hr;
5221     DWORD color;
5222     DWORD shader_code_11[] =  {
5223         0xfffe0101,                                         /* vs_1_1           */
5224         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5225         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5226         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5227         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5228         0x0000ffff                                          /* end              */
5229     };
5230     DWORD shader_code_11_2[] =  {
5231         0xfffe0101,                                         /* vs_1_1           */
5232         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
5233         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
5234         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5235         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5236         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5237         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5238         0x0000ffff                                          /* end              */
5239     };
5240     DWORD shader_code_20[] =  {
5241         0xfffe0200,                                         /* vs_2_0           */
5242         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5243         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5244         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5245         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5246         0x0000ffff                                          /* end              */
5247     };
5248     DWORD shader_code_20_2[] =  {
5249         0xfffe0200,                                         /* vs_2_0           */
5250         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
5251         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
5252         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5253         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5254         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5255         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5256         0x0000ffff                                          /* end              */
5257     };
5258     static const D3DVERTEXELEMENT9 decl_elements[] = {
5259         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5260         D3DDECL_END()
5261     };
5262     float quad1[] = {
5263         -1.0,   -1.0,   0.1,
5264          0.0,   -1.0,   0.1,
5265         -1.0,    0.0,   0.1,
5266          0.0,    0.0,   0.1
5267     };
5268     float quad2[] = {
5269          0.0,   -1.0,   0.1,
5270          1.0,   -1.0,   0.1,
5271          0.0,    0.0,   0.1,
5272          1.0,    0.0,   0.1
5273     };
5274     float quad3[] = {
5275          0.0,    0.0,   0.1,
5276          1.0,    0.0,   0.1,
5277          0.0,    1.0,   0.1,
5278          1.0,    1.0,   0.1
5279     };
5280     float quad4[] = {
5281         -1.0,    0.0,   0.1,
5282          0.0,    0.0,   0.1,
5283         -1.0,    1.0,   0.1,
5284          0.0,    1.0,   0.1
5285     };
5286     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
5287     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
5288
5289     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5290     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5291
5292     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
5293     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5294     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
5295     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5296     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
5297     if(FAILED(hr)) shader_20 = NULL;
5298     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
5299     if(FAILED(hr)) shader_20_2 = NULL;
5300     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5301     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5302
5303     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
5304     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5305     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
5306     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5307     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5308     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5309
5310     hr = IDirect3DDevice9_BeginScene(device);
5311     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5312     if(SUCCEEDED(hr))
5313     {
5314         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
5315         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5316         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5317         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5318
5319         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
5320         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5321         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5322         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5323
5324         if(shader_20) {
5325             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
5326             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5327             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5328             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5329         }
5330
5331         if(shader_20_2) {
5332             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
5333             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5334             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5335             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5336         }
5337
5338         hr = IDirect3DDevice9_EndScene(device);
5339         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5340     }
5341
5342     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5343     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5344     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5345     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5346
5347     color = getPixelColor(device, 160, 360);
5348     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5349        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
5350     color = getPixelColor(device, 480, 360);
5351     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5352        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
5353     if(shader_20) {
5354         color = getPixelColor(device, 480, 120);
5355         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5356            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
5357     }
5358     if(shader_20_2) {
5359         color = getPixelColor(device, 160, 120);
5360         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5361            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5362     }
5363     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5364     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5365
5366     IDirect3DVertexDeclaration9_Release(decl);
5367     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
5368     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
5369     IDirect3DVertexShader9_Release(shader_11_2);
5370     IDirect3DVertexShader9_Release(shader_11);
5371 }
5372
5373 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
5374 {
5375     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
5376     HRESULT hr;
5377     DWORD color;
5378     DWORD shader_code_11[] =  {
5379         0xffff0101,                                         /* ps_1_1           */
5380         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5381         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5382         0x0000ffff                                          /* end              */
5383     };
5384     DWORD shader_code_12[] =  {
5385         0xffff0102,                                         /* ps_1_2           */
5386         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5387         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5388         0x0000ffff                                          /* end              */
5389     };
5390     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
5391      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
5392      * During development of this test, 1.3 shaders were verified too
5393      */
5394     DWORD shader_code_14[] =  {
5395         0xffff0104,                                         /* ps_1_4           */
5396         /* Try to make one constant local. It gets clamped too, although the binary contains
5397          * the bigger numbers
5398          */
5399         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
5400         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5401         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5402         0x0000ffff                                          /* end              */
5403     };
5404     DWORD shader_code_20[] =  {
5405         0xffff0200,                                         /* ps_2_0           */
5406         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5407         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5408         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
5409         0x0000ffff                                          /* end              */
5410     };
5411     float quad1[] = {
5412         -1.0,   -1.0,   0.1,
5413          0.0,   -1.0,   0.1,
5414         -1.0,    0.0,   0.1,
5415          0.0,    0.0,   0.1
5416     };
5417     float quad2[] = {
5418          0.0,   -1.0,   0.1,
5419          1.0,   -1.0,   0.1,
5420          0.0,    0.0,   0.1,
5421          1.0,    0.0,   0.1
5422     };
5423     float quad3[] = {
5424          0.0,    0.0,   0.1,
5425          1.0,    0.0,   0.1,
5426          0.0,    1.0,   0.1,
5427          1.0,    1.0,   0.1
5428     };
5429     float quad4[] = {
5430         -1.0,    0.0,   0.1,
5431          0.0,    0.0,   0.1,
5432         -1.0,    1.0,   0.1,
5433          0.0,    1.0,   0.1
5434     };
5435     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
5436     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
5437
5438     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5439     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5440
5441     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5442     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5443     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5444     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5445     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5446     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5447     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
5448     if(FAILED(hr)) shader_20 = NULL;
5449
5450     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5451     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5452     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5453     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5454     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5455     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5456
5457     hr = IDirect3DDevice9_BeginScene(device);
5458     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5459     if(SUCCEEDED(hr))
5460     {
5461         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5462         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5463         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5464         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5465
5466         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5467         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5468         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5469         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5470
5471         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5472         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5473         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5474         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5475
5476         if(shader_20) {
5477             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
5478             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5479             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5480             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5481         }
5482
5483         hr = IDirect3DDevice9_EndScene(device);
5484         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5485     }
5486     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5487     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5488
5489     color = getPixelColor(device, 160, 360);
5490     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5491        "quad 1 has color %08x, expected 0x00808000\n", color);
5492     color = getPixelColor(device, 480, 360);
5493     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5494        "quad 2 has color %08x, expected 0x00808000\n", color);
5495     color = getPixelColor(device, 480, 120);
5496     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5497        "quad 3 has color %08x, expected 0x00808000\n", color);
5498     if(shader_20) {
5499         color = getPixelColor(device, 160, 120);
5500         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5501            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5502     }
5503     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5504     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5505
5506     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5507     IDirect3DPixelShader9_Release(shader_14);
5508     IDirect3DPixelShader9_Release(shader_12);
5509     IDirect3DPixelShader9_Release(shader_11);
5510 }
5511
5512 static void dp2add_ps_test(IDirect3DDevice9 *device)
5513 {
5514     IDirect3DPixelShader9 *shader_dp2add = NULL;
5515     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5516     HRESULT hr;
5517     DWORD color;
5518
5519     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
5520      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5521      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
5522      * r0 first.
5523      * The result here for the r,g,b components should be roughly 0.5:
5524      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5525     static const DWORD shader_code_dp2add[] =  {
5526         0xffff0200,                                                             /* ps_2_0                       */
5527         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
5528
5529         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5530         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
5531
5532         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
5533         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5534         0x0000ffff                                                              /* end                          */
5535     };
5536
5537     /* Test the _sat modifier, too.  Result here should be:
5538      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5539      *      _SAT: ==> 1.0
5540      *   ADD: (1.0 + -0.5) = 0.5
5541      */
5542     static const DWORD shader_code_dp2add_sat[] =  {
5543         0xffff0200,                                                             /* ps_2_0                           */
5544         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
5545
5546         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
5547         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
5548         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5549
5550         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5551         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5552         0x0000ffff                                                              /* end                              */
5553     };
5554
5555     const float quad[] = {
5556         -1.0,   -1.0,   0.1,
5557          1.0,   -1.0,   0.1,
5558         -1.0,    1.0,   0.1,
5559          1.0,    1.0,   0.1
5560     };
5561
5562
5563     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5564     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5565
5566     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5567     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5568
5569     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5570     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5571
5572     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5573     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5574
5575     if (shader_dp2add) {
5576
5577         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5578         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5579
5580         hr = IDirect3DDevice9_BeginScene(device);
5581         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5582         if(SUCCEEDED(hr))
5583         {
5584             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5585             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5586
5587             hr = IDirect3DDevice9_EndScene(device);
5588             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5589         }
5590
5591         color = getPixelColor(device, 360, 240);
5592         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5593                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5594
5595         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5596         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5597
5598         IDirect3DPixelShader9_Release(shader_dp2add);
5599     } else {
5600         skip("dp2add shader creation failed\n");
5601     }
5602
5603     if (shader_dp2add_sat) {
5604
5605         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5606         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5607
5608         hr = IDirect3DDevice9_BeginScene(device);
5609         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5610         if(SUCCEEDED(hr))
5611         {
5612             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5613             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5614
5615             hr = IDirect3DDevice9_EndScene(device);
5616             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5617         }
5618
5619         color = getPixelColor(device, 360, 240);
5620         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5621                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5622
5623         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5624         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5625
5626         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5627     } else {
5628         skip("dp2add shader creation failed\n");
5629     }
5630
5631     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5632     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5633 }
5634
5635 static void cnd_test(IDirect3DDevice9 *device)
5636 {
5637     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5638     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5639     HRESULT hr;
5640     DWORD color;
5641     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5642      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5643      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5644      */
5645     DWORD shader_code_11[] =  {
5646         0xffff0101,                                                                 /* ps_1_1               */
5647         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5648         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5649         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5650         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5651         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5652         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5653         0x0000ffff                                                                  /* end                  */
5654     };
5655     DWORD shader_code_12[] =  {
5656         0xffff0102,                                                                 /* ps_1_2               */
5657         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5658         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5659         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5660         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5661         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5662         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5663         0x0000ffff                                                                  /* end                  */
5664     };
5665     DWORD shader_code_13[] =  {
5666         0xffff0103,                                                                 /* ps_1_3               */
5667         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5668         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5669         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5670         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5671         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5672         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5673         0x0000ffff                                                                  /* end                  */
5674     };
5675     DWORD shader_code_14[] =  {
5676         0xffff0104,                                                                 /* ps_1_3               */
5677         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5678         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5679         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5680         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5681         0x0000ffff                                                                  /* end                  */
5682     };
5683
5684     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5685      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5686      * set by the compiler, it was added manually after compilation. Note that the COISSUE
5687      * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5688      * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5689      * well enough.
5690      *
5691      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5692      * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5693      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5694      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5695      */
5696     DWORD shader_code_11_coissue[] =  {
5697         0xffff0101,                                                             /* ps_1_1                   */
5698         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5699         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5700         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5701         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5702         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5703         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5704         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5705         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5706         /* 0x40000000 = D3DSI_COISSUE */
5707         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5708         0x0000ffff                                                              /* end                      */
5709     };
5710     DWORD shader_code_12_coissue[] =  {
5711         0xffff0102,                                                             /* ps_1_2                   */
5712         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5713         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5714         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5715         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5716         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5717         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5718         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5719         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5720         /* 0x40000000 = D3DSI_COISSUE */
5721         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5722         0x0000ffff                                                              /* end                      */
5723     };
5724     DWORD shader_code_13_coissue[] =  {
5725         0xffff0103,                                                             /* ps_1_3                   */
5726         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5727         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5728         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5729         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5730         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5731         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5732         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5733         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5734         /* 0x40000000 = D3DSI_COISSUE */
5735         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5736         0x0000ffff                                                              /* end                      */
5737     };
5738     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5739      * compare against 0.5
5740      */
5741     DWORD shader_code_14_coissue[] =  {
5742         0xffff0104,                                                             /* ps_1_4                   */
5743         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5744         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5745         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5746         /* 0x40000000 = D3DSI_COISSUE */
5747         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5748         0x0000ffff                                                              /* end                      */
5749     };
5750     float quad1[] = {
5751         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5752          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5753         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5754          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5755     };
5756     float quad2[] = {
5757          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5758          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5759          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5760          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5761     };
5762     float quad3[] = {
5763          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5764          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5765          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5766          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5767     };
5768     float quad4[] = {
5769         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5770          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5771         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5772          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5773     };
5774     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5775     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5776     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5777     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5778
5779     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5780     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5781
5782     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5783     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5784     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5785     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5786     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5787     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5788     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5789     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5790     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5791     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5792     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5793     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5794     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5795     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5796     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5797     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5798
5799     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5800     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5801     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5802     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5803     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5804     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5805
5806     hr = IDirect3DDevice9_BeginScene(device);
5807     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5808     if(SUCCEEDED(hr))
5809     {
5810         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5811         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5812         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5813         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5814
5815         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5816         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5817         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5818         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5819
5820         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5821         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5822         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5823         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5824
5825         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5826         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5827         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5828         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5829
5830         hr = IDirect3DDevice9_EndScene(device);
5831         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5832     }
5833
5834     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5835     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5836
5837     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5838     color = getPixelColor(device, 158, 118);
5839     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5840     color = getPixelColor(device, 162, 118);
5841     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5842     color = getPixelColor(device, 158, 122);
5843     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5844     color = getPixelColor(device, 162, 122);
5845     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5846
5847     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5848     color = getPixelColor(device, 158, 358);
5849     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5850     color = getPixelColor(device, 162, 358);
5851     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5852         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5853     color = getPixelColor(device, 158, 362);
5854     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5855     color = getPixelColor(device, 162, 362);
5856     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5857         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5858
5859     /* 1.2 shader */
5860     color = getPixelColor(device, 478, 358);
5861     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5862     color = getPixelColor(device, 482, 358);
5863     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5864         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5865     color = getPixelColor(device, 478, 362);
5866     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5867     color = getPixelColor(device, 482, 362);
5868     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5869         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5870
5871     /* 1.3 shader */
5872     color = getPixelColor(device, 478, 118);
5873     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5874     color = getPixelColor(device, 482, 118);
5875     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5876         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5877     color = getPixelColor(device, 478, 122);
5878     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5879     color = getPixelColor(device, 482, 122);
5880     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5881         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5882
5883     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5884     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5885
5886     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5887     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5888     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5889     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5890     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5891     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5892
5893     hr = IDirect3DDevice9_BeginScene(device);
5894     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5895     if(SUCCEEDED(hr))
5896     {
5897         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5898         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5899         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5900         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5901
5902         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5903         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5904         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5905         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5906
5907         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5908         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5909         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5910         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5911
5912         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5913         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5914         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5915         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5916
5917         hr = IDirect3DDevice9_EndScene(device);
5918         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5919     }
5920
5921     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5922     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5923
5924     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5925      * that we swapped the values in c1 and c2 to make the other tests return some color
5926      */
5927     color = getPixelColor(device, 158, 118);
5928     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5929     color = getPixelColor(device, 162, 118);
5930     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5931     color = getPixelColor(device, 158, 122);
5932     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5933     color = getPixelColor(device, 162, 122);
5934     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5935
5936     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5937      * (The Win7 nvidia driver always selects c2)
5938      */
5939     color = getPixelColor(device, 158, 358);
5940     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5941         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5942     color = getPixelColor(device, 162, 358);
5943     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5944         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5945     color = getPixelColor(device, 158, 362);
5946     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5947         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5948     color = getPixelColor(device, 162, 362);
5949     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5950         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5951
5952     /* 1.2 shader */
5953     color = getPixelColor(device, 478, 358);
5954     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5955         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5956     color = getPixelColor(device, 482, 358);
5957     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5958         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5959     color = getPixelColor(device, 478, 362);
5960     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5961         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5962     color = getPixelColor(device, 482, 362);
5963     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5964         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5965
5966     /* 1.3 shader */
5967     color = getPixelColor(device, 478, 118);
5968     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5969         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5970     color = getPixelColor(device, 482, 118);
5971     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5972         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5973     color = getPixelColor(device, 478, 122);
5974     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5975         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5976     color = getPixelColor(device, 482, 122);
5977     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5978         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5979
5980     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5981     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5982
5983     IDirect3DPixelShader9_Release(shader_14_coissue);
5984     IDirect3DPixelShader9_Release(shader_13_coissue);
5985     IDirect3DPixelShader9_Release(shader_12_coissue);
5986     IDirect3DPixelShader9_Release(shader_11_coissue);
5987     IDirect3DPixelShader9_Release(shader_14);
5988     IDirect3DPixelShader9_Release(shader_13);
5989     IDirect3DPixelShader9_Release(shader_12);
5990     IDirect3DPixelShader9_Release(shader_11);
5991 }
5992
5993 static void nested_loop_test(IDirect3DDevice9 *device) {
5994     const DWORD shader_code[] = {
5995         0xffff0300,                                                             /* ps_3_0               */
5996         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5997         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5998         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5999         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
6000         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
6001         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
6002         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
6003         0x0000001d,                                                             /* endloop              */
6004         0x0000001d,                                                             /* endloop              */
6005         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
6006         0x0000ffff                                                              /* end                  */
6007     };
6008     const DWORD vshader_code[] = {
6009         0xfffe0300,                                                             /* vs_3_0               */
6010         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
6011         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
6012         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
6013         0x0000ffff                                                              /* end                  */
6014     };
6015     IDirect3DPixelShader9 *shader;
6016     IDirect3DVertexShader9 *vshader;
6017     HRESULT hr;
6018     DWORD color;
6019     const float quad[] = {
6020         -1.0,   -1.0,   0.1,
6021          1.0,   -1.0,   0.1,
6022         -1.0,    1.0,   0.1,
6023          1.0,    1.0,   0.1
6024     };
6025
6026     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
6027     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
6028     hr = IDirect3DDevice9_SetPixelShader(device, shader);
6029     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
6030     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6031     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
6032     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6033     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
6034     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6035     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6036     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
6037     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6038
6039     hr = IDirect3DDevice9_BeginScene(device);
6040     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6041     if(SUCCEEDED(hr))
6042     {
6043         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6044         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6045         hr = IDirect3DDevice9_EndScene(device);
6046         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6047     }
6048
6049     color = getPixelColor(device, 360, 240);
6050     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
6051        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
6052
6053     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6054     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6055
6056     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6057     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
6058     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6059     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
6060     IDirect3DPixelShader9_Release(shader);
6061     IDirect3DVertexShader9_Release(vshader);
6062 }
6063
6064 struct varying_test_struct
6065 {
6066     const DWORD             *shader_code;
6067     IDirect3DPixelShader9   *shader;
6068     DWORD                   color, color_rhw;
6069     const char              *name;
6070     BOOL                    todo, todo_rhw;
6071 };
6072
6073 struct hugeVertex
6074 {
6075     float pos_x,        pos_y,      pos_z,      rhw;
6076     float weight_1,     weight_2,   weight_3,   weight_4;
6077     float index_1,      index_2,    index_3,    index_4;
6078     float normal_1,     normal_2,   normal_3,   normal_4;
6079     float fog_1,        fog_2,      fog_3,      fog_4;
6080     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
6081     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
6082     float binormal_1,   binormal_2, binormal_3, binormal_4;
6083     float depth_1,      depth_2,    depth_3,    depth_4;
6084     DWORD diffuse, specular;
6085 };
6086
6087 static void pretransformed_varying_test(IDirect3DDevice9 *device) {
6088     /* dcl_position: fails to compile */
6089     const DWORD blendweight_code[] = {
6090         0xffff0300,                             /* ps_3_0                   */
6091         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
6092         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6093         0x0000ffff                              /* end                      */
6094     };
6095     const DWORD blendindices_code[] = {
6096         0xffff0300,                             /* ps_3_0                   */
6097         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
6098         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6099         0x0000ffff                              /* end                      */
6100     };
6101     const DWORD normal_code[] = {
6102         0xffff0300,                             /* ps_3_0                   */
6103         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
6104         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6105         0x0000ffff                              /* end                      */
6106     };
6107     /* psize: fails? */
6108     const DWORD texcoord0_code[] = {
6109         0xffff0300,                             /* ps_3_0                   */
6110         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
6111         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6112         0x0000ffff                              /* end                      */
6113     };
6114     const DWORD tangent_code[] = {
6115         0xffff0300,                             /* ps_3_0                   */
6116         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
6117         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6118         0x0000ffff                              /* end                      */
6119     };
6120     const DWORD binormal_code[] = {
6121         0xffff0300,                             /* ps_3_0                   */
6122         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
6123         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6124         0x0000ffff                              /* end                      */
6125     };
6126     /* tessfactor: fails */
6127     /* positiont: fails */
6128     const DWORD color_code[] = {
6129         0xffff0300,                             /* ps_3_0                   */
6130         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
6131         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6132         0x0000ffff                              /* end                      */
6133     };
6134     const DWORD fog_code[] = {
6135         0xffff0300,                             /* ps_3_0                   */
6136         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
6137         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6138         0x0000ffff                              /* end                      */
6139     };
6140     const DWORD depth_code[] = {
6141         0xffff0300,                             /* ps_3_0                   */
6142         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
6143         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6144         0x0000ffff                              /* end                      */
6145     };
6146     const DWORD specular_code[] = {
6147         0xffff0300,                             /* ps_3_0                   */
6148         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
6149         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6150         0x0000ffff                              /* end                      */
6151     };
6152     /* sample: fails */
6153
6154     struct varying_test_struct tests[] = {
6155        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
6156        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
6157        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
6158        /* Why does dx not forward the texcoord? */
6159        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
6160        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
6161        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
6162        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
6163        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
6164        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
6165        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
6166     };
6167     /* Declare a monster vertex type :-) */
6168     static const D3DVERTEXELEMENT9 decl_elements[] = {
6169         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6170         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
6171         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
6172         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
6173         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
6174         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6175         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
6176         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
6177         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
6178         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6179         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
6180         D3DDECL_END()
6181     };
6182     struct hugeVertex data[4] = {
6183         {
6184             -1.0,   -1.0,   0.1,    1.0,
6185              0.1,    0.1,   0.1,    0.1,
6186              0.2,    0.2,   0.2,    0.2,
6187              0.3,    0.3,   0.3,    0.3,
6188              0.4,    0.4,   0.4,    0.4,
6189              0.50,   0.55,  0.55,   0.55,
6190              0.6,    0.6,   0.6,    0.7,
6191              0.7,    0.7,   0.7,    0.6,
6192              0.8,    0.8,   0.8,    0.8,
6193              0xe6e6e6e6, /* 0.9 * 256 */
6194              0x224488ff  /* Nothing special */
6195         },
6196         {
6197              1.0,   -1.0,   0.1,    1.0,
6198              0.1,    0.1,   0.1,    0.1,
6199              0.2,    0.2,   0.2,    0.2,
6200              0.3,    0.3,   0.3,    0.3,
6201              0.4,    0.4,   0.4,    0.4,
6202              0.50,   0.55,  0.55,   0.55,
6203              0.6,    0.6,   0.6,    0.7,
6204              0.7,    0.7,   0.7,    0.6,
6205              0.8,    0.8,   0.8,    0.8,
6206              0xe6e6e6e6, /* 0.9 * 256 */
6207              0x224488ff /* Nothing special */
6208         },
6209         {
6210             -1.0,    1.0,   0.1,    1.0,
6211              0.1,    0.1,   0.1,    0.1,
6212              0.2,    0.2,   0.2,    0.2,
6213              0.3,    0.3,   0.3,    0.3,
6214              0.4,    0.4,   0.4,    0.4,
6215              0.50,   0.55,  0.55,   0.55,
6216              0.6,    0.6,   0.6,    0.7,
6217              0.7,    0.7,   0.7,    0.6,
6218              0.8,    0.8,   0.8,    0.8,
6219              0xe6e6e6e6, /* 0.9 * 256 */
6220              0x224488ff /* Nothing special */
6221         },
6222         {
6223              1.0,    1.0,   0.1,    1.0,
6224              0.1,    0.1,   0.1,    0.1,
6225              0.2,    0.2,   0.2,    0.2,
6226              0.3,    0.3,   0.3,    0.3,
6227              0.4,    0.4,   0.4,    0.4,
6228              0.50,   0.55,  0.55,   0.55,
6229              0.6,    0.6,   0.6,    0.7,
6230              0.7,    0.7,   0.7,    0.6,
6231              0.8,    0.8,   0.8,    0.8,
6232              0xe6e6e6e6, /* 0.9 * 256 */
6233              0x224488ff /* Nothing special */
6234         },
6235     };
6236     struct hugeVertex data2[4];
6237     IDirect3DVertexDeclaration9 *decl;
6238     HRESULT hr;
6239     unsigned int i;
6240     DWORD color, r, g, b, r_e, g_e, b_e;
6241
6242     memcpy(data2, data, sizeof(data2));
6243     data2[0].pos_x = 0;     data2[0].pos_y = 0;
6244     data2[1].pos_x = 640;   data2[1].pos_y = 0;
6245     data2[2].pos_x = 0;     data2[2].pos_y = 480;
6246     data2[3].pos_x = 640;   data2[3].pos_y = 480;
6247
6248     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6249     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6250     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6251     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6252
6253     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6254     {
6255         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
6256         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
6257            tests[i].name, hr);
6258     }
6259
6260     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6261     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6262     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6263     {
6264         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6265         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6266
6267         hr = IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
6268         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6269
6270         hr = IDirect3DDevice9_BeginScene(device);
6271         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6272         if(SUCCEEDED(hr))
6273         {
6274             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
6275             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6276             hr = IDirect3DDevice9_EndScene(device);
6277             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6278         }
6279
6280         color = getPixelColor(device, 360, 240);
6281         r = color & 0x00ff0000 >> 16;
6282         g = color & 0x0000ff00 >>  8;
6283         b = color & 0x000000ff;
6284         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
6285         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
6286         b_e = tests[i].color_rhw & 0x000000ff;
6287
6288         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6289         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6290
6291         if(tests[i].todo_rhw) {
6292             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
6293              * pipeline
6294              */
6295             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6296                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
6297                          tests[i].name, color, tests[i].color_rhw);
6298         } else {
6299             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6300                "Test %s returned color 0x%08x, expected 0x%08x\n",
6301                tests[i].name, color, tests[i].color_rhw);
6302         }
6303     }
6304
6305     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6306     {
6307         IDirect3DPixelShader9_Release(tests[i].shader);
6308     }
6309
6310     IDirect3DVertexDeclaration9_Release(decl);
6311 }
6312
6313 static void test_compare_instructions(IDirect3DDevice9 *device)
6314 {
6315     DWORD shader_sge_vec_code[] = {
6316         0xfffe0101,                                         /* vs_1_1                   */
6317         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6318         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6319         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6320         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
6321         0x0000ffff                                          /* end                      */
6322     };
6323     DWORD shader_slt_vec_code[] = {
6324         0xfffe0101,                                         /* vs_1_1                   */
6325         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6326         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6327         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6328         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
6329         0x0000ffff                                          /* end                      */
6330     };
6331     DWORD shader_sge_scalar_code[] = {
6332         0xfffe0101,                                         /* vs_1_1                   */
6333         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6334         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6335         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6336         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
6337         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
6338         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
6339         0x0000ffff                                          /* end                      */
6340     };
6341     DWORD shader_slt_scalar_code[] = {
6342         0xfffe0101,                                         /* vs_1_1                   */
6343         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6344         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6345         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6346         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
6347         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
6348         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
6349         0x0000ffff                                          /* end                      */
6350     };
6351     IDirect3DVertexShader9 *shader_sge_vec;
6352     IDirect3DVertexShader9 *shader_slt_vec;
6353     IDirect3DVertexShader9 *shader_sge_scalar;
6354     IDirect3DVertexShader9 *shader_slt_scalar;
6355     HRESULT hr, color;
6356     float quad1[] =  {
6357         -1.0,   -1.0,   0.1,
6358          0.0,   -1.0,   0.1,
6359         -1.0,    0.0,   0.1,
6360          0.0,    0.0,   0.1
6361     };
6362     float quad2[] =  {
6363          0.0,   -1.0,   0.1,
6364          1.0,   -1.0,   0.1,
6365          0.0,    0.0,   0.1,
6366          1.0,    0.0,   0.1
6367     };
6368     float quad3[] =  {
6369         -1.0,    0.0,   0.1,
6370          0.0,    0.0,   0.1,
6371         -1.0,    1.0,   0.1,
6372          0.0,    1.0,   0.1
6373     };
6374     float quad4[] =  {
6375          0.0,    0.0,   0.1,
6376          1.0,    0.0,   0.1,
6377          0.0,    1.0,   0.1,
6378          1.0,    1.0,   0.1
6379     };
6380     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6381     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6382
6383     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6384     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6385
6386     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6387     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6388     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6389     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6390     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6391     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6392     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6393     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6394     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6395     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6396     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6397     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6398     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6399     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6400
6401     hr = IDirect3DDevice9_BeginScene(device);
6402     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6403     if(SUCCEEDED(hr))
6404     {
6405         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6406         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6407         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6408         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6409
6410         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6411         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6412         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6413         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6414
6415         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6416         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6417         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6418         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6419
6420         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6421         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6422
6423         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6424         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6425         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6426         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6427
6428         hr = IDirect3DDevice9_EndScene(device);
6429         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6430     }
6431
6432     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6433     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6434
6435     color = getPixelColor(device, 160, 360);
6436     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6437     color = getPixelColor(device, 480, 360);
6438     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6439     color = getPixelColor(device, 160, 120);
6440     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6441     color = getPixelColor(device, 480, 160);
6442     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6443
6444     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6445     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6446
6447     IDirect3DVertexShader9_Release(shader_sge_vec);
6448     IDirect3DVertexShader9_Release(shader_slt_vec);
6449     IDirect3DVertexShader9_Release(shader_sge_scalar);
6450     IDirect3DVertexShader9_Release(shader_slt_scalar);
6451 }
6452
6453 static void test_vshader_input(IDirect3DDevice9 *device)
6454 {
6455     static const DWORD swapped_shader_code_3[] =
6456     {
6457         0xfffe0300,                                         /* vs_3_0               */
6458         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6459         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6460         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6461         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6462         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6463         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6464         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6465         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6466         0x0000ffff                                          /* end                  */
6467     };
6468     static const DWORD swapped_shader_code_1[] =
6469     {
6470         0xfffe0101,                                         /* vs_1_1               */
6471         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6472         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6473         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6474         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6475         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6476         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6477         0x0000ffff                                          /* end                  */
6478     };
6479     static const DWORD swapped_shader_code_2[] =
6480     {
6481         0xfffe0200,                                         /* vs_2_0               */
6482         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6483         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6484         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6485         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6486         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6487         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6488         0x0000ffff                                          /* end                  */
6489     };
6490     static const DWORD texcoord_color_shader_code_3[] =
6491     {
6492         0xfffe0300,                                         /* vs_3_0               */
6493         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6494         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6495         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6496         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6497         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6498         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6499         0x0000ffff                                          /* end                  */
6500     };
6501     static const DWORD texcoord_color_shader_code_2[] =
6502     {
6503         0xfffe0200,                                         /* vs_2_0               */
6504         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6505         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6506         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6507         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6508         0x0000ffff                                          /* end                  */
6509     };
6510     static const DWORD texcoord_color_shader_code_1[] =
6511     {
6512         0xfffe0101,                                         /* vs_1_1               */
6513         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6514         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6515         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6516         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6517         0x0000ffff                                          /* end                  */
6518     };
6519     static const DWORD color_color_shader_code_3[] =
6520     {
6521         0xfffe0300,                                         /* vs_3_0               */
6522         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6523         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6524         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6525         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6526         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6527         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6528         0x0000ffff                                          /* end                  */
6529     };
6530     static const DWORD color_color_shader_code_2[] =
6531     {
6532         0xfffe0200,                                         /* vs_2_0               */
6533         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6534         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6535         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6536         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6537         0x0000ffff                                          /* end                  */
6538     };
6539     static const DWORD color_color_shader_code_1[] =
6540     {
6541         0xfffe0101,                                         /* vs_1_1               */
6542         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6543         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6544         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6545         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6546         0x0000ffff                                          /* end                  */
6547     };
6548     static const DWORD ps3_code[] =
6549     {
6550         0xffff0300,                                         /* ps_3_0               */
6551         0x0200001f, 0x8000000a, 0x900f0000,                 /* dcl_color0 v0        */
6552         0x02000001, 0x800f0800, 0x90e40000,                 /* mov oC0, v0          */
6553         0x0000ffff                                          /* end                  */
6554     };
6555     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6556     IDirect3DPixelShader9 *ps;
6557     HRESULT hr;
6558     DWORD color;
6559     float quad1[] =  {
6560         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6561          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6562         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6563          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6564     };
6565     float quad2[] =  {
6566          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6567          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6568          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6569          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6570     };
6571     float quad3[] =  {
6572         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6573          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6574         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6575          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6576     };
6577     float quad4[] =  {
6578          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6579          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6580          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6581          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6582     };
6583     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6584         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6585         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6586         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6587         D3DDECL_END()
6588     };
6589     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6590         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6591         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6592         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6593         D3DDECL_END()
6594     };
6595     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6596         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6597         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6598         D3DDECL_END()
6599     };
6600     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6601         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6602         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6603         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6604         D3DDECL_END()
6605     };
6606     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6607         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6608         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6609         D3DDECL_END()
6610     };
6611     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6612         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6613         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6614         D3DDECL_END()
6615     };
6616     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6617         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6618         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6619         D3DDECL_END()
6620     };
6621     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6622         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6623         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6624         D3DDECL_END()
6625     };
6626     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6627     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6628     unsigned int i;
6629     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6630     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6631
6632     struct vertex quad1_color[] =  {
6633        {-1.0,   -1.0,   0.1,    0x00ff8040},
6634        { 0.0,   -1.0,   0.1,    0x00ff8040},
6635        {-1.0,    0.0,   0.1,    0x00ff8040},
6636        { 0.0,    0.0,   0.1,    0x00ff8040}
6637     };
6638     struct vertex quad2_color[] =  {
6639        { 0.0,   -1.0,   0.1,    0x00ff8040},
6640        { 1.0,   -1.0,   0.1,    0x00ff8040},
6641        { 0.0,    0.0,   0.1,    0x00ff8040},
6642        { 1.0,    0.0,   0.1,    0x00ff8040}
6643     };
6644     struct vertex quad3_color[] =  {
6645        {-1.0,    0.0,   0.1,    0x00ff8040},
6646        { 0.0,    0.0,   0.1,    0x00ff8040},
6647        {-1.0,    1.0,   0.1,    0x00ff8040},
6648        { 0.0,    1.0,   0.1,    0x00ff8040}
6649     };
6650     float quad4_color[] =  {
6651          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6652          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6653          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6654          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6655     };
6656
6657     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6658     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6659     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6660     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6661     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6662     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6663     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6664     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6665
6666     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6667     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6668     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6669     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6670     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6671     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6672     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6673     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6674
6675     hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
6676     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6677
6678     for(i = 1; i <= 3; i++) {
6679         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6680         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6681         if(i == 3) {
6682             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6683             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6684             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6685             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6686         } else if(i == 2){
6687             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6688             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6689         } else if(i == 1) {
6690             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6691             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6692         }
6693
6694         hr = IDirect3DDevice9_BeginScene(device);
6695         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6696         if(SUCCEEDED(hr))
6697         {
6698             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6699             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6700
6701             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6702             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6703             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6704             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6705
6706             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6707             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6708             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6709             if(i == 3 || i == 2) {
6710                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6711             } else if(i == 1) {
6712                 /* Succeeds or fails, depending on SW or HW vertex processing */
6713                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6714             }
6715
6716             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6717             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6718             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6719             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6720
6721             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6722             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6723             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6724             if(i == 3 || i == 2) {
6725                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6726             } else if(i == 1) {
6727                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6728             }
6729
6730             hr = IDirect3DDevice9_EndScene(device);
6731             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6732         }
6733
6734         if(i == 3 || i == 2) {
6735             color = getPixelColor(device, 160, 360);
6736             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6737                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6738
6739             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6740             color = getPixelColor(device, 480, 360);
6741             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6742                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6743             color = getPixelColor(device, 160, 120);
6744             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6745             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6746                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6747
6748             color = getPixelColor(device, 480, 160);
6749             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6750         } else if(i == 1) {
6751             color = getPixelColor(device, 160, 360);
6752             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6753                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6754             color = getPixelColor(device, 480, 360);
6755             /* Accept the clear color as well in this case, since SW VP returns an error */
6756             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6757             color = getPixelColor(device, 160, 120);
6758             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6759                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6760             color = getPixelColor(device, 480, 160);
6761             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6762         }
6763
6764         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6765         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6766
6767         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6768         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6769
6770         /* Now find out if the whole streams are re-read, or just the last active value for the
6771          * vertices is used.
6772          */
6773         hr = IDirect3DDevice9_BeginScene(device);
6774         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6775         if(SUCCEEDED(hr))
6776         {
6777             float quad1_modified[] =  {
6778                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6779                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6780                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6781                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6782             };
6783             float quad2_modified[] =  {
6784                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6785                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6786                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6787                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6788             };
6789
6790             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6791             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6792
6793             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6794             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6795             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6796             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6797
6798             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6799             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6800             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6801             if(i == 3 || i == 2) {
6802                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6803             } else if(i == 1) {
6804                 /* Succeeds or fails, depending on SW or HW vertex processing */
6805                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6806             }
6807
6808             hr = IDirect3DDevice9_EndScene(device);
6809             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6810         }
6811
6812         color = getPixelColor(device, 480, 350);
6813         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6814          * as well.
6815          *
6816          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6817          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6818          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6819          * refrast's result.
6820          *
6821          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6822          */
6823         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6824            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6825
6826         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6827         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6828
6829         IDirect3DDevice9_SetVertexShader(device, NULL);
6830         IDirect3DDevice9_SetPixelShader(device, NULL);
6831         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6832
6833         IDirect3DVertexShader9_Release(swapped_shader);
6834     }
6835
6836     for(i = 1; i <= 3; i++) {
6837         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6838         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6839         if(i == 3) {
6840             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6841             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6842             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6843             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6844             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6845             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6846         } else if(i == 2){
6847             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6848             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6849             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6850             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6851         } else if(i == 1) {
6852             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6853             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6854             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6855             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6856         }
6857
6858         hr = IDirect3DDevice9_BeginScene(device);
6859         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6860         if(SUCCEEDED(hr))
6861         {
6862             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6863             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6864             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6865             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6866             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6867             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6868
6869             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6870             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6871
6872             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6873             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6874             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6875             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6876             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6877             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6878
6879             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6880             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6881             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6882             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6883             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6884             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6885
6886             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6887             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6888             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6889             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6890
6891             hr = IDirect3DDevice9_EndScene(device);
6892             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6893         }
6894         IDirect3DDevice9_SetVertexShader(device, NULL);
6895         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6896         IDirect3DDevice9_SetPixelShader(device, NULL);
6897
6898         color = getPixelColor(device, 160, 360);
6899         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6900            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6901         color = getPixelColor(device, 480, 360);
6902         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6903            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6904         color = getPixelColor(device, 160, 120);
6905         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6906            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6907         color = getPixelColor(device, 480, 160);
6908         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6909            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6910
6911         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6912         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6913
6914         IDirect3DVertexShader9_Release(texcoord_color_shader);
6915         IDirect3DVertexShader9_Release(color_color_shader);
6916     }
6917
6918     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6919     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6920     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6921     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6922
6923     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6924     IDirect3DVertexDeclaration9_Release(decl_color_color);
6925     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6926     IDirect3DVertexDeclaration9_Release(decl_color_float);
6927
6928     IDirect3DPixelShader9_Release(ps);
6929 }
6930
6931 static void srgbtexture_test(IDirect3DDevice9 *device)
6932 {
6933     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6934      * texture stage state to render a quad using that texture.  The resulting
6935      * color components should be 0x36 (~ 0.21), per this formula:
6936      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6937      * This is true where srgb_color > 0.04045.
6938      */
6939     IDirect3D9 *d3d = NULL;
6940     HRESULT hr;
6941     LPDIRECT3DTEXTURE9 texture = NULL;
6942     LPDIRECT3DSURFACE9 surface = NULL;
6943     D3DLOCKED_RECT lr;
6944     DWORD color;
6945     float quad[] = {
6946         -1.0,       1.0,       0.0,     0.0,    0.0,
6947          1.0,       1.0,       0.0,     1.0,    0.0,
6948         -1.0,      -1.0,       0.0,     0.0,    1.0,
6949          1.0,      -1.0,       0.0,     1.0,    1.0,
6950     };
6951
6952
6953     memset(&lr, 0, sizeof(lr));
6954     IDirect3DDevice9_GetDirect3D(device, &d3d);
6955     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6956                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6957                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6958         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6959         goto out;
6960     }
6961
6962     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6963                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6964                                         &texture, NULL);
6965     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6966     if(!texture) {
6967         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6968         goto out;
6969     }
6970     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6971     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6972
6973     fill_surface(surface, 0xff7f7f7f);
6974     IDirect3DSurface9_Release(surface);
6975
6976     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6977     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6978     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6979     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6980
6981     hr = IDirect3DDevice9_BeginScene(device);
6982     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6983     if(SUCCEEDED(hr))
6984     {
6985         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6986         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6987
6988         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6989         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6990
6991
6992         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6993         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6994
6995         hr = IDirect3DDevice9_EndScene(device);
6996         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6997     }
6998
6999     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7000     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
7001     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
7002     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
7003
7004     color = getPixelColor(device, 320, 240);
7005     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
7006
7007     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7008     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7009
7010 out:
7011     if(texture) IDirect3DTexture9_Release(texture);
7012     IDirect3D9_Release(d3d);
7013 }
7014
7015 static void shademode_test(IDirect3DDevice9 *device)
7016 {
7017     /* Render a quad and try all of the different fixed function shading models. */
7018     HRESULT hr;
7019     DWORD color0, color1;
7020     DWORD color0_gouraud = 0, color1_gouraud = 0;
7021     DWORD shademode = D3DSHADE_FLAT;
7022     DWORD primtype = D3DPT_TRIANGLESTRIP;
7023     LPVOID data = NULL;
7024     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
7025     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
7026     UINT i, j;
7027     struct vertex quad_strip[] =
7028     {
7029         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
7030         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
7031         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
7032         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
7033     };
7034     struct vertex quad_list[] =
7035     {
7036         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
7037         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
7038         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
7039
7040         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
7041         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
7042         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
7043     };
7044
7045     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
7046                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
7047     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7048     if (FAILED(hr)) goto bail;
7049
7050     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
7051                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
7052     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7053     if (FAILED(hr)) goto bail;
7054
7055     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7056     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7057
7058     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7059     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7060
7061     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
7062     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7063     memcpy(data, quad_strip, sizeof(quad_strip));
7064     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
7065     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7066
7067     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
7068     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7069     memcpy(data, quad_list, sizeof(quad_list));
7070     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
7071     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7072
7073     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
7074      * the color fixups we have to do for FLAT shading will be dependent on that. */
7075     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
7076     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7077
7078     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
7079     for (j=0; j<2; j++) {
7080
7081         /* Inner loop just changes the D3DRS_SHADEMODE */
7082         for (i=0; i<3; i++) {
7083             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7084             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7085
7086             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
7087             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7088
7089             hr = IDirect3DDevice9_BeginScene(device);
7090             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7091             if(SUCCEEDED(hr))
7092             {
7093                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
7094                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
7095
7096                 hr = IDirect3DDevice9_EndScene(device);
7097                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7098             }
7099
7100             /* Sample two spots from the output */
7101             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
7102             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
7103             switch(shademode) {
7104                 case D3DSHADE_FLAT:
7105                     /* Should take the color of the first vertex of each triangle */
7106                     if (0)
7107                     {
7108                         /* This test depends on EXT_provoking_vertex being
7109                          * available. This extension is currently (20090810)
7110                          * not common enough to let the test fail if it isn't
7111                          * present. */
7112                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
7113                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
7114                     }
7115                     shademode = D3DSHADE_GOURAUD;
7116                     break;
7117                 case D3DSHADE_GOURAUD:
7118                     /* Should be an interpolated blend */
7119
7120                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7121                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
7122                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7123                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
7124
7125                     color0_gouraud = color0;
7126                     color1_gouraud = color1;
7127
7128                     shademode = D3DSHADE_PHONG;
7129                     break;
7130                 case D3DSHADE_PHONG:
7131                     /* Should be the same as GOURAUD, since no hardware implements this */
7132                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7133                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
7134                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7135                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7136
7137                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7138                             color0_gouraud, color0);
7139                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7140                             color1_gouraud, color1);
7141                     break;
7142             }
7143         }
7144
7145         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7146         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7147
7148         /* Now, do it all over again with a TRIANGLELIST */
7149         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7150         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7151         primtype = D3DPT_TRIANGLELIST;
7152         shademode = D3DSHADE_FLAT;
7153     }
7154
7155 bail:
7156     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7157     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7158     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7159     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7160
7161     if (vb_strip)
7162         IDirect3DVertexBuffer9_Release(vb_strip);
7163     if (vb_list)
7164         IDirect3DVertexBuffer9_Release(vb_list);
7165 }
7166
7167 static void alpha_test(IDirect3DDevice9 *device)
7168 {
7169     HRESULT hr;
7170     IDirect3DTexture9 *offscreenTexture;
7171     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7172     DWORD color;
7173
7174     struct vertex quad1[] =
7175     {
7176         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
7177         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
7178         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
7179         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
7180     };
7181     struct vertex quad2[] =
7182     {
7183         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
7184         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
7185         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
7186         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
7187     };
7188     static const float composite_quad[][5] = {
7189         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7190         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
7191         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7192         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
7193     };
7194
7195     /* Clear the render target with alpha = 0.5 */
7196     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7197     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7198
7199     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7200     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7201
7202     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7203     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7204     if(!backbuffer) {
7205         goto out;
7206     }
7207
7208     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7209     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7210     if(!offscreen) {
7211         goto out;
7212     }
7213
7214     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7215     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7216
7217     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7218     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7219     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7220     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7221     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7222     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7223     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7224     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7225     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7226     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7227
7228     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7229     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7230     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7231
7232         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7233         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7234         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7235         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7236         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7237         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7238         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7239
7240         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7241         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7242         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7243         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7244         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7245         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7246
7247         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7248          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7249          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7250         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7251         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7252         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7253         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7254
7255         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7256         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7257         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7258         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7259         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7260         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7261
7262         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7263         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7264         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7265         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7266         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7267         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7268
7269         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7270         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7271
7272         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7273          * Disable alpha blending for the final composition
7274          */
7275         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7276         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7277         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7278         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7279
7280         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7281         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7282         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7283         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7284         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7285         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7286
7287         hr = IDirect3DDevice9_EndScene(device);
7288         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7289     }
7290
7291     color = getPixelColor(device, 160, 360);
7292     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7293        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7294
7295     color = getPixelColor(device, 160, 120);
7296     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7297        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7298
7299     color = getPixelColor(device, 480, 360);
7300     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7301        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7302
7303     color = getPixelColor(device, 480, 120);
7304     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7305        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7306
7307     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7308
7309     out:
7310     /* restore things */
7311     if(backbuffer) {
7312         IDirect3DSurface9_Release(backbuffer);
7313     }
7314     if(offscreenTexture) {
7315         IDirect3DTexture9_Release(offscreenTexture);
7316     }
7317     if(offscreen) {
7318         IDirect3DSurface9_Release(offscreen);
7319     }
7320 }
7321
7322 struct vertex_shortcolor {
7323     float x, y, z;
7324     unsigned short r, g, b, a;
7325 };
7326 struct vertex_floatcolor {
7327     float x, y, z;
7328     float r, g, b, a;
7329 };
7330
7331 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7332 {
7333     HRESULT hr;
7334     BOOL s_ok, ub_ok, f_ok;
7335     DWORD color, size, i;
7336     void *data;
7337     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7338         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7339         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7340         D3DDECL_END()
7341     };
7342     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7343         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7344         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7345         D3DDECL_END()
7346     };
7347     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7348         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7349         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7350         D3DDECL_END()
7351     };
7352     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7353         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7354         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7355         D3DDECL_END()
7356     };
7357     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7358         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7359         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7360         D3DDECL_END()
7361     };
7362     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7363         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7364         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7365         D3DDECL_END()
7366     };
7367     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7368         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
7369         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7370         D3DDECL_END()
7371     };
7372     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7373     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7374     IDirect3DVertexBuffer9 *vb, *vb2;
7375     struct vertex quad1[] =                             /* D3DCOLOR */
7376     {
7377         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
7378         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7379         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
7380         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7381     };
7382     struct vertex quad2[] =                             /* UBYTE4N */
7383     {
7384         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7385         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
7386         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7387         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
7388     };
7389     struct vertex_shortcolor quad3[] =                  /* short */
7390     {
7391         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7392         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7393         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7394         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7395     };
7396     struct vertex_floatcolor quad4[] =
7397     {
7398         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7399         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7400         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7401         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7402     };
7403     DWORD colors[] = {
7404         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7405         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7406         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7407         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7408         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7409         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7410         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7411         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7412         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7413         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7414         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7415         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7416         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7417         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7418         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7419         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7420     };
7421     float quads[] = {
7422         -1.0,   -1.0,     0.1,
7423         -1.0,    0.0,     0.1,
7424          0.0,   -1.0,     0.1,
7425          0.0,    0.0,     0.1,
7426
7427          0.0,   -1.0,     0.1,
7428          0.0,    0.0,     0.1,
7429          1.0,   -1.0,     0.1,
7430          1.0,    0.0,     0.1,
7431
7432          0.0,    0.0,     0.1,
7433          0.0,    1.0,     0.1,
7434          1.0,    0.0,     0.1,
7435          1.0,    1.0,     0.1,
7436
7437         -1.0,    0.0,     0.1,
7438         -1.0,    1.0,     0.1,
7439          0.0,    0.0,     0.1,
7440          0.0,    1.0,     0.1
7441     };
7442     struct tvertex quad_transformed[] = {
7443        {  90,    110,     0.1,      2.0,        0x00ffff00},
7444        { 570,    110,     0.1,      2.0,        0x00ffff00},
7445        {  90,    300,     0.1,      2.0,        0x00ffff00},
7446        { 570,    300,     0.1,      2.0,        0x00ffff00}
7447     };
7448     D3DCAPS9 caps;
7449
7450     memset(&caps, 0, sizeof(caps));
7451     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7452     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7453
7454     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7455     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7456
7457     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7458     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7459     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7460     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7461     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7462     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7463     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7464         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7465         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7466         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7467         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7468     } else {
7469         trace("D3DDTCAPS_UBYTE4N not supported\n");
7470         dcl_ubyte_2 = NULL;
7471         dcl_ubyte = NULL;
7472     }
7473     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7474     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7475     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7476     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7477
7478     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7479     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7480                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7481     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7482
7483     hr = IDirect3DDevice9_BeginScene(device);
7484     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7485     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7486     if(SUCCEEDED(hr)) {
7487         if(dcl_color) {
7488             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7489             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7490             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7491             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7492         }
7493
7494         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7495          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7496          * using software vertex processing. Doh!
7497          */
7498         if(dcl_ubyte) {
7499             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7500             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7501             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7502             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7503             ub_ok = SUCCEEDED(hr);
7504         }
7505
7506         if(dcl_short) {
7507             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7508             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7509             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7510             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7511             s_ok = SUCCEEDED(hr);
7512         }
7513
7514         if(dcl_float) {
7515             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7516             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7517             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7518             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7519             f_ok = SUCCEEDED(hr);
7520         }
7521
7522         hr = IDirect3DDevice9_EndScene(device);
7523         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7524     }
7525
7526     if(dcl_short) {
7527         color = getPixelColor(device, 480, 360);
7528         ok(color == 0x000000ff || !s_ok,
7529            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7530     }
7531     if(dcl_ubyte) {
7532         color = getPixelColor(device, 160, 120);
7533         ok(color == 0x0000ffff || !ub_ok,
7534            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7535     }
7536     if(dcl_color) {
7537         color = getPixelColor(device, 160, 360);
7538         ok(color == 0x00ffff00,
7539            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7540     }
7541     if(dcl_float) {
7542         color = getPixelColor(device, 480, 120);
7543         ok(color == 0x00ff0000 || !f_ok,
7544            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7545     }
7546     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7547
7548     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7549      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7550      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7551      * whether the immediate mode code works
7552      */
7553     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7554     hr = IDirect3DDevice9_BeginScene(device);
7555     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7556     if(SUCCEEDED(hr)) {
7557         if(dcl_color) {
7558             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7559             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7560             memcpy(data, quad1, sizeof(quad1));
7561             hr = IDirect3DVertexBuffer9_Unlock(vb);
7562             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7563             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7564             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7565             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7566             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7567             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7568             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7569         }
7570
7571         if(dcl_ubyte) {
7572             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7573             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7574             memcpy(data, quad2, sizeof(quad2));
7575             hr = IDirect3DVertexBuffer9_Unlock(vb);
7576             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7577             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7578             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7579             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7580             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7581             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7582             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7583                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7584             ub_ok = SUCCEEDED(hr);
7585         }
7586
7587         if(dcl_short) {
7588             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7589             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7590             memcpy(data, quad3, sizeof(quad3));
7591             hr = IDirect3DVertexBuffer9_Unlock(vb);
7592             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7593             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7594             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7595             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7596             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7597             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7598             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7599                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7600             s_ok = SUCCEEDED(hr);
7601         }
7602
7603         if(dcl_float) {
7604             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7605             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7606             memcpy(data, quad4, sizeof(quad4));
7607             hr = IDirect3DVertexBuffer9_Unlock(vb);
7608             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7609             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7610             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7611             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7612             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7613             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7614             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7615                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7616             f_ok = SUCCEEDED(hr);
7617         }
7618
7619         hr = IDirect3DDevice9_EndScene(device);
7620         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7621     }
7622
7623     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7624     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7625     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7626     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7627
7628     if(dcl_short) {
7629         color = getPixelColor(device, 480, 360);
7630         ok(color == 0x000000ff || !s_ok,
7631            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7632     }
7633     if(dcl_ubyte) {
7634         color = getPixelColor(device, 160, 120);
7635         ok(color == 0x0000ffff || !ub_ok,
7636            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7637     }
7638     if(dcl_color) {
7639         color = getPixelColor(device, 160, 360);
7640         ok(color == 0x00ffff00,
7641            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7642     }
7643     if(dcl_float) {
7644         color = getPixelColor(device, 480, 120);
7645         ok(color == 0x00ff0000 || !f_ok,
7646            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7647     }
7648     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7649
7650     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7651     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7652
7653     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7654     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7655     memcpy(data, quad_transformed, sizeof(quad_transformed));
7656     hr = IDirect3DVertexBuffer9_Unlock(vb);
7657     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7658
7659     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7660     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7661
7662     hr = IDirect3DDevice9_BeginScene(device);
7663     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7664     if(SUCCEEDED(hr)) {
7665         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7666         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7667         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7668         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7669
7670         hr = IDirect3DDevice9_EndScene(device);
7671         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7672     }
7673
7674     color = getPixelColor(device, 88, 108);
7675     ok(color == 0x000000ff,
7676        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7677     color = getPixelColor(device, 92, 108);
7678     ok(color == 0x000000ff,
7679        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7680     color = getPixelColor(device, 88, 112);
7681     ok(color == 0x000000ff,
7682        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7683     color = getPixelColor(device, 92, 112);
7684     ok(color == 0x00ffff00,
7685        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7686
7687     color = getPixelColor(device, 568, 108);
7688     ok(color == 0x000000ff,
7689        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7690     color = getPixelColor(device, 572, 108);
7691     ok(color == 0x000000ff,
7692        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7693     color = getPixelColor(device, 568, 112);
7694     ok(color == 0x00ffff00,
7695        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7696     color = getPixelColor(device, 572, 112);
7697     ok(color == 0x000000ff,
7698        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7699
7700     color = getPixelColor(device, 88, 298);
7701     ok(color == 0x000000ff,
7702        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7703     color = getPixelColor(device, 92, 298);
7704     ok(color == 0x00ffff00,
7705        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7706     color = getPixelColor(device, 88, 302);
7707     ok(color == 0x000000ff,
7708        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7709     color = getPixelColor(device, 92, 302);
7710     ok(color == 0x000000ff,
7711        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7712
7713     color = getPixelColor(device, 568, 298);
7714     ok(color == 0x00ffff00,
7715        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7716     color = getPixelColor(device, 572, 298);
7717     ok(color == 0x000000ff,
7718        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7719     color = getPixelColor(device, 568, 302);
7720     ok(color == 0x000000ff,
7721        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7722     color = getPixelColor(device, 572, 302);
7723     ok(color == 0x000000ff,
7724        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7725
7726     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7727
7728     /* This test is pointless without those two declarations: */
7729     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7730         skip("color-ubyte switching test declarations aren't supported\n");
7731         goto out;
7732     }
7733
7734     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7735     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7736     memcpy(data, quads, sizeof(quads));
7737     hr = IDirect3DVertexBuffer9_Unlock(vb);
7738     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7739     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7740                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7741     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7742     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7743     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7744     memcpy(data, colors, sizeof(colors));
7745     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7746     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7747
7748     for(i = 0; i < 2; i++) {
7749         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7750         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7751
7752         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7753         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7754         if(i == 0) {
7755             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7756         } else {
7757             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7758         }
7759         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7760
7761         hr = IDirect3DDevice9_BeginScene(device);
7762         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7763         ub_ok = FALSE;
7764         if(SUCCEEDED(hr)) {
7765             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7766             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7767             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7768             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7769                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7770             ub_ok = SUCCEEDED(hr);
7771
7772             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7773             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7774             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7775             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7776
7777             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7778             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7779             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7780             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7781                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7782             ub_ok = (SUCCEEDED(hr) && ub_ok);
7783
7784             hr = IDirect3DDevice9_EndScene(device);
7785             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7786         }
7787
7788         if(i == 0) {
7789             color = getPixelColor(device, 480, 360);
7790             ok(color == 0x00ff0000,
7791                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7792             color = getPixelColor(device, 160, 120);
7793             ok(color == 0x00ffffff,
7794                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7795             color = getPixelColor(device, 160, 360);
7796             ok(color == 0x000000ff || !ub_ok,
7797                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7798             color = getPixelColor(device, 480, 120);
7799             ok(color == 0x000000ff || !ub_ok,
7800                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7801         } else {
7802             color = getPixelColor(device, 480, 360);
7803             ok(color == 0x000000ff,
7804                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7805             color = getPixelColor(device, 160, 120);
7806             ok(color == 0x00ffffff,
7807                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7808             color = getPixelColor(device, 160, 360);
7809             ok(color == 0x00ff0000 || !ub_ok,
7810                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7811             color = getPixelColor(device, 480, 120);
7812             ok(color == 0x00ff0000 || !ub_ok,
7813                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7814         }
7815         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7816     }
7817
7818     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7819     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7820     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7821     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7822     IDirect3DVertexBuffer9_Release(vb2);
7823
7824     out:
7825     IDirect3DVertexBuffer9_Release(vb);
7826     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7827     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7828     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7829     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7830     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7831     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7832     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7833 }
7834
7835 struct vertex_float16color {
7836     float x, y, z;
7837     DWORD c1, c2;
7838 };
7839
7840 static void test_vshader_float16(IDirect3DDevice9 *device)
7841 {
7842     HRESULT hr;
7843     DWORD color;
7844     void *data;
7845     static const D3DVERTEXELEMENT9 decl_elements[] = {
7846         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7847         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7848         D3DDECL_END()
7849     };
7850     IDirect3DVertexDeclaration9 *vdecl = NULL;
7851     IDirect3DVertexBuffer9 *buffer = NULL;
7852     IDirect3DVertexShader9 *shader;
7853     DWORD shader_code[] = {
7854         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7855         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7856         0x90e40001, 0x0000ffff
7857     };
7858     struct vertex_float16color quad[] = {
7859         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7860         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7861         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7862         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7863
7864         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7865         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7866         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7867         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7868
7869         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7870         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7871         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7872         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7873
7874         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7875         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7876         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7877         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7878     };
7879
7880     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7881     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7882
7883     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7884     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7885     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7886     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7887     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7888     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7889
7890     hr = IDirect3DDevice9_BeginScene(device);
7891     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7892     if(SUCCEEDED(hr)) {
7893         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7894         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7895         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7896         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7897         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7898         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7899         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7900         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7901         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7902         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7903
7904         hr = IDirect3DDevice9_EndScene(device);
7905         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7906     }
7907     color = getPixelColor(device, 480, 360);
7908     ok(color == 0x00ff0000,
7909        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7910     color = getPixelColor(device, 160, 120);
7911     ok(color == 0x00000000,
7912        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7913     color = getPixelColor(device, 160, 360);
7914     ok(color == 0x0000ff00,
7915        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7916     color = getPixelColor(device, 480, 120);
7917     ok(color == 0x000000ff,
7918        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7919     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7920
7921     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7922     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7923
7924     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7925                                              D3DPOOL_MANAGED, &buffer, NULL);
7926     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7927     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7928     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7929     memcpy(data, quad, sizeof(quad));
7930     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7931     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7932     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7933     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7934
7935     hr = IDirect3DDevice9_BeginScene(device);
7936     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7937     if(SUCCEEDED(hr)) {
7938             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7939             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7940             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7941             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7942             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7943             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7944             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7945             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7946
7947             hr = IDirect3DDevice9_EndScene(device);
7948             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7949     }
7950
7951     color = getPixelColor(device, 480, 360);
7952     ok(color == 0x00ff0000,
7953        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7954     color = getPixelColor(device, 160, 120);
7955     ok(color == 0x00000000,
7956        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7957     color = getPixelColor(device, 160, 360);
7958     ok(color == 0x0000ff00,
7959        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7960     color = getPixelColor(device, 480, 120);
7961     ok(color == 0x000000ff,
7962        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7963     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7964
7965     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7966     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7967     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7968     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7969     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7970     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7971
7972     IDirect3DVertexDeclaration9_Release(vdecl);
7973     IDirect3DVertexShader9_Release(shader);
7974     IDirect3DVertexBuffer9_Release(buffer);
7975 }
7976
7977 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7978 {
7979     D3DCAPS9 caps;
7980     IDirect3DTexture9 *texture;
7981     HRESULT hr;
7982     D3DLOCKED_RECT rect;
7983     unsigned int x, y;
7984     DWORD *dst, color;
7985     const float quad[] = {
7986         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7987          1.0,   -1.0,   0.1,    1.2,   -0.2,
7988         -1.0,    1.0,   0.1,   -0.2,    1.2,
7989          1.0,    1.0,   0.1,    1.2,    1.2
7990     };
7991     memset(&caps, 0, sizeof(caps));
7992
7993     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7994     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7995     if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
7996     {
7997         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7998         ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
7999                 "Card has conditional NP2 support without power of two restriction set\n");
8000     }
8001     else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
8002     {
8003         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
8004         return;
8005     }
8006     else
8007     {
8008         skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
8009         return;
8010     }
8011
8012     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8013     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8014
8015     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
8016     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8017
8018     memset(&rect, 0, sizeof(rect));
8019     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
8020     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8021     for(y = 0; y < 10; y++) {
8022         for(x = 0; x < 10; x++) {
8023             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
8024             if(x == 0 || x == 9 || y == 0 || y == 9) {
8025                 *dst = 0x00ff0000;
8026             } else {
8027                 *dst = 0x000000ff;
8028             }
8029         }
8030     }
8031     hr = IDirect3DTexture9_UnlockRect(texture, 0);
8032     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8033
8034     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8035     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8036     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
8037     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8038     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
8039     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8040     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8041     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8042
8043     hr = IDirect3DDevice9_BeginScene(device);
8044     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8045     if(SUCCEEDED(hr)) {
8046         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8047         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8048
8049         hr = IDirect3DDevice9_EndScene(device);
8050         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8051     }
8052
8053     color = getPixelColor(device,    1,  1);
8054     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
8055     color = getPixelColor(device, 639, 479);
8056     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
8057
8058     color = getPixelColor(device, 135, 101);
8059     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
8060     color = getPixelColor(device, 140, 101);
8061     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
8062     color = getPixelColor(device, 135, 105);
8063     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
8064     color = getPixelColor(device, 140, 105);
8065     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
8066
8067     color = getPixelColor(device, 135, 376);
8068     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
8069     color = getPixelColor(device, 140, 376);
8070     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
8071     color = getPixelColor(device, 135, 379);
8072     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
8073     color = getPixelColor(device, 140, 379);
8074     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
8075
8076     color = getPixelColor(device, 500, 101);
8077     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
8078     color = getPixelColor(device, 504, 101);
8079     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
8080     color = getPixelColor(device, 500, 105);
8081     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
8082     color = getPixelColor(device, 504, 105);
8083     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
8084
8085     color = getPixelColor(device, 500, 376);
8086     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
8087     color = getPixelColor(device, 504, 376);
8088     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
8089     color = getPixelColor(device, 500, 380);
8090     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
8091     color = getPixelColor(device, 504, 380);
8092     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
8093
8094     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8095
8096     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8097     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8098     IDirect3DTexture9_Release(texture);
8099 }
8100
8101 static void vFace_register_test(IDirect3DDevice9 *device)
8102 {
8103     HRESULT hr;
8104     DWORD color;
8105     const DWORD shader_code[] = {
8106         0xffff0300,                                                             /* ps_3_0                     */
8107         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8108         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
8109         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
8110         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
8111         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
8112         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8113         0x0000ffff                                                              /* END                        */
8114     };
8115     const DWORD vshader_code[] = {
8116         0xfffe0300,                                                             /* vs_3_0               */
8117         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8118         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8119         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8120         0x0000ffff                                                              /* end                  */
8121     };
8122     IDirect3DPixelShader9 *shader;
8123     IDirect3DVertexShader9 *vshader;
8124     IDirect3DTexture9 *texture;
8125     IDirect3DSurface9 *surface, *backbuffer;
8126     const float quad[] = {
8127         -1.0,   -1.0,   0.1,
8128          1.0,   -1.0,   0.1,
8129         -1.0,    0.0,   0.1,
8130
8131          1.0,   -1.0,   0.1,
8132          1.0,    0.0,   0.1,
8133         -1.0,    0.0,   0.1,
8134
8135         -1.0,    0.0,   0.1,
8136         -1.0,    1.0,   0.1,
8137          1.0,    0.0,   0.1,
8138
8139          1.0,    0.0,   0.1,
8140         -1.0,    1.0,   0.1,
8141          1.0,    1.0,   0.1,
8142     };
8143     const float blit[] = {
8144          0.0,   -1.0,   0.1,    0.0,    0.0,
8145          1.0,   -1.0,   0.1,    1.0,    0.0,
8146          0.0,    1.0,   0.1,    0.0,    1.0,
8147          1.0,    1.0,   0.1,    1.0,    1.0,
8148     };
8149
8150     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8151     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8152     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8153     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8154     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8155     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8156     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8157     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8158     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8159     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8160     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8161     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8162     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8163     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8164     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8165     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8166
8167     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8168     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8169
8170     hr = IDirect3DDevice9_BeginScene(device);
8171     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8172     if(SUCCEEDED(hr)) {
8173         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8174         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8175         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8176         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8177         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8178         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8179         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8180         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8181         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8182         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8183         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8184
8185         /* Blit the texture onto the back buffer to make it visible */
8186         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8187         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
8188         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8189         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8190         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8191         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8192         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8193         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8194         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8195         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8196         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8197         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8198
8199         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8200         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8201
8202         hr = IDirect3DDevice9_EndScene(device);
8203         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8204     }
8205
8206     color = getPixelColor(device, 160, 360);
8207     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8208     color = getPixelColor(device, 160, 120);
8209     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8210     color = getPixelColor(device, 480, 360);
8211     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8212     color = getPixelColor(device, 480, 120);
8213     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8214     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8215     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8216
8217     IDirect3DDevice9_SetTexture(device, 0, NULL);
8218     IDirect3DPixelShader9_Release(shader);
8219     IDirect3DVertexShader9_Release(vshader);
8220     IDirect3DSurface9_Release(surface);
8221     IDirect3DSurface9_Release(backbuffer);
8222     IDirect3DTexture9_Release(texture);
8223 }
8224
8225 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8226 {
8227     HRESULT hr;
8228     DWORD color;
8229     int i;
8230     D3DCAPS9 caps;
8231     BOOL L6V5U5_supported = FALSE;
8232     IDirect3DTexture9 *tex1, *tex2;
8233     D3DLOCKED_RECT locked_rect;
8234
8235     static const float quad[][7] = {
8236         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8237         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8238         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8239         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8240     };
8241
8242     static const D3DVERTEXELEMENT9 decl_elements[] = {
8243         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8244         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8245         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8246         D3DDECL_END()
8247     };
8248
8249     /* use asymmetric matrix to test loading */
8250     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8251     float scale, offset;
8252
8253     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8254     IDirect3DTexture9           *texture            = NULL;
8255
8256     memset(&caps, 0, sizeof(caps));
8257     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8258     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8259     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8260         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8261         return;
8262     } else {
8263         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8264          * They report that it is not supported, but after that bump mapping works properly. So just test
8265          * if the format is generally supported, and check the BUMPENVMAP flag
8266          */
8267         IDirect3D9 *d3d9;
8268
8269         IDirect3DDevice9_GetDirect3D(device, &d3d9);
8270         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8271                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8272         L6V5U5_supported = SUCCEEDED(hr);
8273         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8274                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8275         IDirect3D9_Release(d3d9);
8276         if(FAILED(hr)) {
8277             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8278             return;
8279         }
8280     }
8281
8282     /* Generate the textures */
8283     generate_bumpmap_textures(device);
8284
8285     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8286     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8287     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8288     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8289     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8290     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8291     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8292     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8293
8294     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8295     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8296     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8297     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8298     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8299     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8300
8301     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8302     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8303     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8304     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8305     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8306     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8307
8308     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8309     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8310
8311     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8312     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8313
8314     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8315     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8316
8317
8318     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8319     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8320     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8321     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8322
8323     hr = IDirect3DDevice9_BeginScene(device);
8324     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8325
8326     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8327     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8328
8329     hr = IDirect3DDevice9_EndScene(device);
8330     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8331
8332     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8333      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8334      * But since testing the color match is not the purpose of the test don't be too picky
8335      */
8336     color = getPixelColor(device, 320-32, 240);
8337     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8338     color = getPixelColor(device, 320+32, 240);
8339     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8340     color = getPixelColor(device, 320, 240-32);
8341     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8342     color = getPixelColor(device, 320, 240+32);
8343     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8344     color = getPixelColor(device, 320, 240);
8345     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8346     color = getPixelColor(device, 320+32, 240+32);
8347     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8348     color = getPixelColor(device, 320-32, 240+32);
8349     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8350     color = getPixelColor(device, 320+32, 240-32);
8351     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8352     color = getPixelColor(device, 320-32, 240-32);
8353     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8354     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8355     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8356
8357     for(i = 0; i < 2; i++) {
8358         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8359         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8360         IDirect3DTexture9_Release(texture); /* For the GetTexture */
8361         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8362         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8363         IDirect3DTexture9_Release(texture); /* To destroy it */
8364     }
8365
8366     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8367         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8368         goto cleanup;
8369     }
8370     if(L6V5U5_supported == FALSE) {
8371         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8372         goto cleanup;
8373     }
8374
8375     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8376     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8377     /* This test only tests the luminance part. The bumpmapping part was already tested above and
8378      * would only make this test more complicated
8379      */
8380     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8381     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8382     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8383     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8384
8385     memset(&locked_rect, 0, sizeof(locked_rect));
8386     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8387     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8388     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8389     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8390     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8391
8392     memset(&locked_rect, 0, sizeof(locked_rect));
8393     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8394     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8395     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8396     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8397     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8398
8399     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8400     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8401     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8402     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8403
8404     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8405     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8406     scale = 2.0;
8407     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8408     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8409     offset = 0.1;
8410     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8411     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8412
8413     hr = IDirect3DDevice9_BeginScene(device);
8414     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8415     if(SUCCEEDED(hr)) {
8416         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8417         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8418         hr = IDirect3DDevice9_EndScene(device);
8419         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8420     }
8421
8422     color = getPixelColor(device, 320, 240);
8423     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
8424      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
8425      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8426      */
8427     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8428     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8429     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8430
8431     /* Check a result scale factor > 1.0 */
8432     scale = 10;
8433     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8434     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8435     offset = 10;
8436     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8437     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8438
8439     hr = IDirect3DDevice9_BeginScene(device);
8440     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8441     if(SUCCEEDED(hr)) {
8442         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8443         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8444         hr = IDirect3DDevice9_EndScene(device);
8445         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8446     }
8447     color = getPixelColor(device, 320, 240);
8448     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8449     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8450     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8451
8452     /* Check clamping in the scale factor calculation */
8453     scale = 1000;
8454     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8455     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8456     offset = -1;
8457     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8458     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8459
8460     hr = IDirect3DDevice9_BeginScene(device);
8461     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8462     if(SUCCEEDED(hr)) {
8463         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8464         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8465         hr = IDirect3DDevice9_EndScene(device);
8466         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8467     }
8468     color = getPixelColor(device, 320, 240);
8469     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8470     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8471     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8472
8473     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8474     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8475     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8476     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8477
8478     IDirect3DTexture9_Release(tex1);
8479     IDirect3DTexture9_Release(tex2);
8480
8481 cleanup:
8482     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8483     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8484     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8485     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8486
8487     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8488     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8489     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8490 }
8491
8492 static void stencil_cull_test(IDirect3DDevice9 *device) {
8493     HRESULT hr;
8494     IDirect3DSurface9 *depthstencil = NULL;
8495     D3DSURFACE_DESC desc;
8496     float quad1[] = {
8497         -1.0,   -1.0,   0.1,
8498          0.0,   -1.0,   0.1,
8499         -1.0,    0.0,   0.1,
8500          0.0,    0.0,   0.1,
8501     };
8502     float quad2[] = {
8503          0.0,   -1.0,   0.1,
8504          1.0,   -1.0,   0.1,
8505          0.0,    0.0,   0.1,
8506          1.0,    0.0,   0.1,
8507     };
8508     float quad3[] = {
8509         0.0,    0.0,   0.1,
8510         1.0,    0.0,   0.1,
8511         0.0,    1.0,   0.1,
8512         1.0,    1.0,   0.1,
8513     };
8514     float quad4[] = {
8515         -1.0,    0.0,   0.1,
8516          0.0,    0.0,   0.1,
8517         -1.0,    1.0,   0.1,
8518          0.0,    1.0,   0.1,
8519     };
8520     struct vertex painter[] = {
8521        {-1.0,   -1.0,   0.0,    0x00000000},
8522        { 1.0,   -1.0,   0.0,    0x00000000},
8523        {-1.0,    1.0,   0.0,    0x00000000},
8524        { 1.0,    1.0,   0.0,    0x00000000},
8525     };
8526     WORD indices_cw[]  = {0, 1, 3};
8527     WORD indices_ccw[] = {0, 2, 3};
8528     unsigned int i;
8529     DWORD color;
8530
8531     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8532     if(depthstencil == NULL) {
8533         skip("No depth stencil buffer\n");
8534         return;
8535     }
8536     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8537     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8538     IDirect3DSurface9_Release(depthstencil);
8539     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8540         skip("No 4 or 8 bit stencil surface\n");
8541         return;
8542     }
8543
8544     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8545     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8546     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8547     ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
8548
8549     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8550     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8551     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8552     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8553     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8554     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8555     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8556     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8557
8558     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8559     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8560     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8561     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8562     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8563     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8564
8565     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8566     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8567     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8568     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8569
8570     /* First pass: Fill the stencil buffer with some values... */
8571     hr = IDirect3DDevice9_BeginScene(device);
8572     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8573     if(SUCCEEDED(hr))
8574     {
8575         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8576         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8577         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8578                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8579         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8580         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8581                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8582         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8583
8584         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8585         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8586         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8587         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8588         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8589                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8590         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8591         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8592                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8593         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8594
8595         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8596         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8597         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8598                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8599         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8600         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8601                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8602         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8603
8604         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8605         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8606         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8607                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8608         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8609         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8610                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8611         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8612
8613         hr = IDirect3DDevice9_EndScene(device);
8614         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8615     }
8616
8617     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8618     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8619     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8620     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8621     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8622     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8623     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8624     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8625     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8626     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8627     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8628     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8629     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8630
8631     /* 2nd pass: Make the stencil values visible */
8632     hr = IDirect3DDevice9_BeginScene(device);
8633     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8634     if(SUCCEEDED(hr))
8635     {
8636         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8637         ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8638         for (i = 0; i < 16; ++i)
8639         {
8640             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8641             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8642
8643             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8644             painter[1].diffuse = (i * 16);
8645             painter[2].diffuse = (i * 16);
8646             painter[3].diffuse = (i * 16);
8647             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8648             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8649         }
8650         hr = IDirect3DDevice9_EndScene(device);
8651         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8652     }
8653
8654     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8655     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8656
8657     color = getPixelColor(device, 160, 420);
8658     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8659     color = getPixelColor(device, 160, 300);
8660     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8661
8662     color = getPixelColor(device, 480, 420);
8663     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8664     color = getPixelColor(device, 480, 300);
8665     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8666
8667     color = getPixelColor(device, 160, 180);
8668     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8669     color = getPixelColor(device, 160, 60);
8670     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8671
8672     color = getPixelColor(device, 480, 180);
8673     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8674     color = getPixelColor(device, 480, 60);
8675     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8676
8677     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8678     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8679 }
8680
8681 static void vpos_register_test(IDirect3DDevice9 *device)
8682 {
8683     HRESULT hr;
8684     DWORD color;
8685     const DWORD shader_code[] = {
8686     0xffff0300,                                                             /* ps_3_0                     */
8687     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8688     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8689     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8690     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8691     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8692     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8693     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8694     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8695     0x0000ffff                                                              /* end                        */
8696     };
8697     const DWORD shader_frac_code[] = {
8698     0xffff0300,                                                             /* ps_3_0                     */
8699     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8700     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8701     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8702     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8703     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8704     0x0000ffff                                                              /* end                        */
8705     };
8706     const DWORD vshader_code[] = {
8707         0xfffe0300,                                                             /* vs_3_0               */
8708         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8709         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8710         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8711         0x0000ffff                                                              /* end                  */
8712     };
8713     IDirect3DVertexShader9 *vshader;
8714     IDirect3DPixelShader9 *shader, *shader_frac;
8715     IDirect3DSurface9 *surface = NULL, *backbuffer;
8716     const float quad[] = {
8717         -1.0,   -1.0,   0.1,    0.0,    0.0,
8718          1.0,   -1.0,   0.1,    1.0,    0.0,
8719         -1.0,    1.0,   0.1,    0.0,    1.0,
8720          1.0,    1.0,   0.1,    1.0,    1.0,
8721     };
8722     D3DLOCKED_RECT lr;
8723     float constant[4] = {1.0, 0.0, 320, 240};
8724     DWORD *pos;
8725
8726     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8727     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8728     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8729     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8730     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8731     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8732     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8733     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8734     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8735     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8736     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8737     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8738     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8739     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8740     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8741     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8742
8743     hr = IDirect3DDevice9_BeginScene(device);
8744     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8745     if(SUCCEEDED(hr)) {
8746         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8747         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8748         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8749         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8750         hr = IDirect3DDevice9_EndScene(device);
8751         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8752     }
8753
8754     /* This has to be pixel exact */
8755     color = getPixelColor(device, 319, 239);
8756     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8757     color = getPixelColor(device, 320, 239);
8758     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8759     color = getPixelColor(device, 319, 240);
8760     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8761     color = getPixelColor(device, 320, 240);
8762     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8763     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8764
8765     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8766                                              &surface, NULL);
8767     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8768     hr = IDirect3DDevice9_BeginScene(device);
8769     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8770     if(SUCCEEDED(hr)) {
8771         constant[2] = 16; constant[3] = 16;
8772         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8773         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8774         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8775         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8776         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8777         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8778         hr = IDirect3DDevice9_EndScene(device);
8779         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8780     }
8781     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8782     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8783
8784     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8785     color = *pos & 0x00ffffff;
8786     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8787     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8788     color = *pos & 0x00ffffff;
8789     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8790     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8791     color = *pos & 0x00ffffff;
8792     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8793     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8794     color = *pos & 0x00ffffff;
8795     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8796
8797     hr = IDirect3DSurface9_UnlockRect(surface);
8798     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8799
8800     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8801      * have full control over the multisampling setting inside this test
8802      */
8803     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8804     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8805     hr = IDirect3DDevice9_BeginScene(device);
8806     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8807     if(SUCCEEDED(hr)) {
8808         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8809         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8810         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8811         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8812         hr = IDirect3DDevice9_EndScene(device);
8813         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8814     }
8815     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8816     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8817
8818     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8819     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8820
8821     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8822     color = *pos & 0x00ffffff;
8823     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8824
8825     hr = IDirect3DSurface9_UnlockRect(surface);
8826     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8827
8828     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8829     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8830     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8831     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8832     IDirect3DPixelShader9_Release(shader);
8833     IDirect3DPixelShader9_Release(shader_frac);
8834     IDirect3DVertexShader9_Release(vshader);
8835     if(surface) IDirect3DSurface9_Release(surface);
8836     IDirect3DSurface9_Release(backbuffer);
8837 }
8838
8839 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8840 {
8841     D3DCOLOR color;
8842
8843     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8844     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8845     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8846     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8847     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8848
8849     ++r;
8850     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8851     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8852     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8853     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8854     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8855
8856     return TRUE;
8857 }
8858
8859 static void pointsize_test(IDirect3DDevice9 *device)
8860 {
8861     HRESULT hr;
8862     D3DCAPS9 caps;
8863     D3DMATRIX matrix;
8864     D3DMATRIX identity;
8865     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8866     DWORD color;
8867     IDirect3DSurface9 *rt, *backbuffer;
8868     IDirect3DTexture9 *tex1, *tex2;
8869     RECT rect = {0, 0, 128, 128};
8870     D3DLOCKED_RECT lr;
8871     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8872                                 0x00000000, 0x00000000};
8873     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8874                                 0x00000000, 0x0000ff00};
8875
8876     const float vertices[] = {
8877         64,     64,     0.1,
8878         128,    64,     0.1,
8879         192,    64,     0.1,
8880         256,    64,     0.1,
8881         320,    64,     0.1,
8882         384,    64,     0.1,
8883         448,    64,     0.1,
8884         512,    64,     0.1,
8885     };
8886
8887     /* 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 */
8888     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;
8889     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;
8890     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;
8891     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;
8892
8893     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;
8894     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;
8895     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;
8896     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;
8897
8898     memset(&caps, 0, sizeof(caps));
8899     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8900     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8901     if(caps.MaxPointSize < 32.0) {
8902         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8903         return;
8904     }
8905
8906     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8907     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8908     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8909     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8910     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8911     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8912     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8913     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8914
8915     hr = IDirect3DDevice9_BeginScene(device);
8916     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8917     if (SUCCEEDED(hr))
8918     {
8919         ptsize = 15.0;
8920         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8921         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8922         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8923         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8924
8925         ptsize = 31.0;
8926         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8927         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8928         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8929         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8930
8931         ptsize = 30.75;
8932         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8933         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8934         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8935         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8936
8937         if (caps.MaxPointSize >= 63.0)
8938         {
8939             ptsize = 63.0;
8940             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8941             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8942             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8943             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8944
8945             ptsize = 62.75;
8946             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8947             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8948             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8949             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8950         }
8951
8952         ptsize = 1.0;
8953         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8954         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8955         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8956         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8957
8958         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8959         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8960         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8961         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8962
8963         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8964         ptsize = 15.0;
8965         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8966         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8967         ptsize = 1.0;
8968         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8969         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8970         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8971         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8972
8973         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8974         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8975
8976         /* pointsize < pointsize_min < pointsize_max?
8977          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8978         ptsize = 1.0;
8979         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8980         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8981         ptsize = 15.0;
8982         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8983         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8984         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8985         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8986
8987         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8988         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8989
8990         hr = IDirect3DDevice9_EndScene(device);
8991         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8992     }
8993
8994     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8995     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8996     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8997
8998     if (caps.MaxPointSize >= 63.0)
8999     {
9000         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
9001         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
9002     }
9003
9004     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
9005     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
9006     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
9007     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
9008     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
9009
9010     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9011
9012     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
9013      * generates texture coordinates for the point(result: Yes, it does)
9014      *
9015      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
9016      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
9017      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
9018      */
9019     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
9020     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9021
9022     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
9023     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9024     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9025     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9026     memset(&lr, 0, sizeof(lr));
9027     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
9028     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9029     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
9030     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9031     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9032     memset(&lr, 0, sizeof(lr));
9033     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
9034     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9035     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
9036     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9037     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9038     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9039     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9040     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9041     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9042     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9043     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9044     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9045     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9046     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9047     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9048     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9049     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9050     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9051     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9052
9053     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
9054     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9055     ptsize = 32.0;
9056     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9057     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9058
9059     hr = IDirect3DDevice9_BeginScene(device);
9060     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9061     if(SUCCEEDED(hr))
9062     {
9063         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9064         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9065         hr = IDirect3DDevice9_EndScene(device);
9066         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9067     }
9068
9069     color = getPixelColor(device, 64-4, 64-4);
9070     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
9071     color = getPixelColor(device, 64-4, 64+4);
9072     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
9073     color = getPixelColor(device, 64+4, 64+4);
9074     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
9075     color = getPixelColor(device, 64+4, 64-4);
9076     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
9077     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9078
9079     U(matrix).m[0][0] =  1.0f / 64.0f;
9080     U(matrix).m[1][1] = -1.0f / 64.0f;
9081     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
9082     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
9083
9084     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
9085     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
9086
9087     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
9088             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
9089     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
9090
9091     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
9092     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9093     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
9094     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
9095
9096     hr = IDirect3DDevice9_BeginScene(device);
9097     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9098     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9099     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9100     hr = IDirect3DDevice9_EndScene(device);
9101     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9102
9103     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
9104     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
9105     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9106     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9107     IDirect3DSurface9_Release(backbuffer);
9108     IDirect3DSurface9_Release(rt);
9109
9110     color = getPixelColor(device, 64-4, 64-4);
9111     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
9112             "Expected color 0x00ff0000, got 0x%08x.\n", color);
9113     color = getPixelColor(device, 64+4, 64-4);
9114     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
9115             "Expected color 0x00ffff00, got 0x%08x.\n", color);
9116     color = getPixelColor(device, 64-4, 64+4);
9117     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
9118             "Expected color 0x00000000, got 0x%08x.\n", color);
9119     color = getPixelColor(device, 64+4, 64+4);
9120     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9121             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9122
9123     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9124     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9125
9126     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9127     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9128     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9129     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9130     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9131     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9132     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9133     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9134     IDirect3DTexture9_Release(tex1);
9135     IDirect3DTexture9_Release(tex2);
9136
9137     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9138     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9139     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9140     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9141     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9142     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9143 }
9144
9145 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9146 {
9147     static const DWORD vshader_code[] =
9148     {
9149         0xfffe0300,                                                             /* vs_3_0                     */
9150         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0            */
9151         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0            */
9152         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                 */
9153         0x0000ffff                                                              /* end                        */
9154     };
9155     static const DWORD pshader_code1[] =
9156     {
9157         0xffff0300,                                                             /* ps_3_0                     */
9158         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9159         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
9160         0x0000ffff                                                              /* end                        */
9161     };
9162     static const DWORD pshader_code2[] =
9163     {
9164         0xffff0300,                                                             /* ps_3_0                     */
9165         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9166         0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
9167         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
9168         0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1                */
9169         0x0000ffff                                                              /* end                        */
9170     };
9171
9172     HRESULT hr;
9173     IDirect3DVertexShader9 *vs;
9174     IDirect3DPixelShader9 *ps1, *ps2;
9175     IDirect3DTexture9 *tex1, *tex2;
9176     IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
9177     D3DCAPS9 caps;
9178     DWORD color;
9179     UINT i, j;
9180     float quad[] = {
9181        -1.0,   -1.0,    0.1,
9182         1.0,   -1.0,    0.1,
9183        -1.0,    1.0,    0.1,
9184         1.0,    1.0,    0.1,
9185     };
9186     float texquad[] = {
9187        -1.0,   -1.0,    0.1,    0.0,    0.0,
9188         0.0,   -1.0,    0.1,    1.0,    0.0,
9189        -1.0,    1.0,    0.1,    0.0,    1.0,
9190         0.0,    1.0,    0.1,    1.0,    1.0,
9191
9192         0.0,   -1.0,    0.1,    0.0,    0.0,
9193         1.0,   -1.0,    0.1,    1.0,    0.0,
9194         0.0,    1.0,    0.1,    0.0,    1.0,
9195         1.0,    1.0,    0.1,    1.0,    1.0,
9196     };
9197
9198     memset(&caps, 0, sizeof(caps));
9199     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9200     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9201     if(caps.NumSimultaneousRTs < 2) {
9202         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9203         return;
9204     }
9205
9206     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9207     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9208
9209     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
9210             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
9211     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
9212
9213     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9214             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9215     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9216     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9217             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9218     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9219     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
9220     ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
9221     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
9222     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9223     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
9224     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9225
9226     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9227     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9228     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9229     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9230     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9231     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9232
9233     hr = IDirect3DDevice9_SetVertexShader(device, vs);
9234     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9235     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9236     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9237     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9238     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9239     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9240     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9241
9242     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
9243     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9244     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9245     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9246     color = getPixelColorFromSurface(readback, 8, 8);
9247     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9248             "Expected color 0x000000ff, got 0x%08x.\n", color);
9249     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9250     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9251     color = getPixelColorFromSurface(readback, 8, 8);
9252     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9253             "Expected color 0x000000ff, got 0x%08x.\n", color);
9254
9255     /* Render targets not written by the pixel shader should be unmodified. */
9256     hr = IDirect3DDevice9_SetPixelShader(device, ps1);
9257     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9258     hr = IDirect3DDevice9_BeginScene(device);
9259     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9260     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9261     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9262     hr = IDirect3DDevice9_EndScene(device);
9263     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9264     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9265     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9266     color = getPixelColorFromSurface(readback, 8, 8);
9267     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9268             "Expected color 0xff00ff00, got 0x%08x.\n", color);
9269     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9270     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9271     for (i = 6; i < 10; ++i)
9272     {
9273         for (j = 6; j < 10; ++j)
9274         {
9275             color = getPixelColorFromSurface(readback, j, i);
9276             ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9277                     "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
9278         }
9279     }
9280
9281     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9282     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9283     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9284     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9285     color = getPixelColorFromSurface(readback, 8, 8);
9286     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9287             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9288     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9289     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9290     color = getPixelColorFromSurface(readback, 8, 8);
9291     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9292             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9293
9294     hr = IDirect3DDevice9_SetPixelShader(device, ps2);
9295     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9296
9297     hr = IDirect3DDevice9_BeginScene(device);
9298     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9299     if(SUCCEEDED(hr)) {
9300         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9301         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9302
9303         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9304         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9305         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9306         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9307         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9308         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9309         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9310         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9311         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9312         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9313
9314         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9315         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9316         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9317         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9318
9319         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9320         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9321         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9322         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9323
9324         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9325         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9326
9327         hr = IDirect3DDevice9_EndScene(device);
9328         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9329     }
9330
9331     color = getPixelColor(device, 160, 240);
9332     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9333     color = getPixelColor(device, 480, 240);
9334     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9335     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9336
9337     IDirect3DPixelShader9_Release(ps2);
9338     IDirect3DPixelShader9_Release(ps1);
9339     IDirect3DVertexShader9_Release(vs);
9340     IDirect3DTexture9_Release(tex1);
9341     IDirect3DTexture9_Release(tex2);
9342     IDirect3DSurface9_Release(surf1);
9343     IDirect3DSurface9_Release(surf2);
9344     IDirect3DSurface9_Release(backbuf);
9345     IDirect3DSurface9_Release(readback);
9346 }
9347
9348 struct formats {
9349     const char *fmtName;
9350     D3DFORMAT textureFormat;
9351     DWORD resultColorBlending;
9352     DWORD resultColorNoBlending;
9353 };
9354
9355 static const struct formats test_formats[] = {
9356   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9357   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9358   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9359   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9360   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9361   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9362   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9363   { NULL, 0 }
9364 };
9365
9366 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9367 {
9368     HRESULT hr;
9369     IDirect3DTexture9 *offscreenTexture = NULL;
9370     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9371     IDirect3D9 *d3d = NULL;
9372     DWORD color;
9373     DWORD r0, g0, b0, r1, g1, b1;
9374     int fmt_index;
9375
9376     static const float quad[][5] = {
9377         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9378         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
9379         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9380         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
9381     };
9382
9383     /* Quad with R=0x10, G=0x20 */
9384     static const struct vertex quad1[] = {
9385         {-1.0f, -1.0f, 0.1f, 0x80102000},
9386         {-1.0f,  1.0f, 0.1f, 0x80102000},
9387         { 1.0f, -1.0f, 0.1f, 0x80102000},
9388         { 1.0f,  1.0f, 0.1f, 0x80102000},
9389     };
9390
9391     /* Quad with R=0x20, G=0x10 */
9392     static const struct vertex quad2[] = {
9393         {-1.0f, -1.0f, 0.1f, 0x80201000},
9394         {-1.0f,  1.0f, 0.1f, 0x80201000},
9395         { 1.0f, -1.0f, 0.1f, 0x80201000},
9396         { 1.0f,  1.0f, 0.1f, 0x80201000},
9397     };
9398
9399     IDirect3DDevice9_GetDirect3D(device, &d3d);
9400
9401     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9402     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9403     if(!backbuffer) {
9404         goto out;
9405     }
9406
9407     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9408     {
9409         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9410
9411         if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9412                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
9413         {
9414             skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
9415             continue;
9416         }
9417
9418         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9419         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9420
9421         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9422         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9423         if(!offscreenTexture) {
9424             continue;
9425         }
9426
9427         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9428         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9429         if(!offscreen) {
9430             continue;
9431         }
9432
9433         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9434         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9435
9436         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9437         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9438         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9439         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9440         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9441         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9442         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9443         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9444         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9445         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9446
9447         /* Below we will draw two quads with different colors and try to blend them together.
9448          * The result color is compared with the expected outcome.
9449          */
9450         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9451             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9452             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9453             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9454             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9455
9456             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9457             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9458
9459             /* Draw a quad using color 0x0010200 */
9460             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9461             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9462             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9463             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9464             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9465             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9466
9467             /* Draw a quad using color 0x0020100 */
9468             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9469             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9470             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9471             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9472             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9473             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9474
9475             /* We don't want to blend the result on the backbuffer */
9476             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9477             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9478
9479             /* Prepare rendering the 'blended' texture quad to the backbuffer */
9480             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9481             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9482             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9483             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9484
9485             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9486             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9487
9488             /* This time with the texture */
9489             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9490             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9491
9492             IDirect3DDevice9_EndScene(device);
9493         }
9494
9495         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9496             /* Compare the color of the center quad with our expectation */
9497             color = getPixelColor(device, 320, 240);
9498             r0 = (color & 0x00ff0000) >> 16;
9499             g0 = (color & 0x0000ff00) >>  8;
9500             b0 = (color & 0x000000ff) >>  0;
9501
9502             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9503             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9504             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9505
9506             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9507                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9508                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9509                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9510         } else {
9511             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9512              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9513              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9514             color = getPixelColor(device, 320, 240);
9515             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);
9516         }
9517         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9518
9519         IDirect3DDevice9_SetTexture(device, 0, NULL);
9520         if(offscreenTexture) {
9521             IDirect3DTexture9_Release(offscreenTexture);
9522         }
9523         if(offscreen) {
9524             IDirect3DSurface9_Release(offscreen);
9525         }
9526     }
9527
9528 out:
9529     /* restore things */
9530     if(backbuffer) {
9531         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9532         IDirect3DSurface9_Release(backbuffer);
9533     }
9534 }
9535
9536 static void tssargtemp_test(IDirect3DDevice9 *device)
9537 {
9538     HRESULT hr;
9539     DWORD color;
9540     static const struct vertex quad[] = {
9541         {-1.0,     -1.0,    0.1,    0x00ff0000},
9542         { 1.0,     -1.0,    0.1,    0x00ff0000},
9543         {-1.0,      1.0,    0.1,    0x00ff0000},
9544         { 1.0,      1.0,    0.1,    0x00ff0000}
9545     };
9546     D3DCAPS9 caps;
9547
9548     memset(&caps, 0, sizeof(caps));
9549     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9550     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9551     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9552         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9553         return;
9554     }
9555
9556     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9557     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9558
9559     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9560     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9561     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9562     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9563
9564     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9565     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9566     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9567     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9568     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9569     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9570
9571     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9572     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9573     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9574     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9575     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9576     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9577
9578     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9579     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9580
9581     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9582     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9583     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9584     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9585
9586     hr = IDirect3DDevice9_BeginScene(device);
9587     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9588     if(SUCCEEDED(hr)) {
9589         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9590         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9591         hr = IDirect3DDevice9_EndScene(device);
9592         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9593     }
9594     color = getPixelColor(device, 320, 240);
9595     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9596     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9597
9598     /* Set stage 1 back to default */
9599     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9600     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9601     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9602     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9603     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9604     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9605     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9606     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9607     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9608     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9609 }
9610
9611 struct testdata
9612 {
9613     DWORD idxVertex; /* number of instances in the first stream */
9614     DWORD idxColor; /* number of instances in the second stream */
9615     DWORD idxInstance; /* should be 1 ?? */
9616     DWORD color1; /* color 1 instance */
9617     DWORD color2; /* color 2 instance */
9618     DWORD color3; /* color 3 instance */
9619     DWORD color4; /* color 4 instance */
9620     WORD strVertex; /* specify which stream to use 0-2*/
9621     WORD strColor;
9622     WORD strInstance;
9623 };
9624
9625 static const struct testdata testcases[]=
9626 {
9627     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9628     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9629     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9630     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9631     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  4 */
9632     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9633     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9634     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9635     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  8 */
9636     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /*  9 */
9637     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9638     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9639     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9640     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9641 /*
9642     This draws one instance on some machines, no instance on others
9643     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9644 */
9645 /*
9646     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9647     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9648 */
9649 };
9650
9651 /* Drawing Indexed Geometry with instances*/
9652 static void stream_test(IDirect3DDevice9 *device)
9653 {
9654     IDirect3DVertexBuffer9 *vb = NULL;
9655     IDirect3DVertexBuffer9 *vb2 = NULL;
9656     IDirect3DVertexBuffer9 *vb3 = NULL;
9657     IDirect3DIndexBuffer9 *ib = NULL;
9658     IDirect3DVertexDeclaration9 *pDecl = NULL;
9659     IDirect3DVertexShader9 *shader = NULL;
9660     HRESULT hr;
9661     BYTE *data;
9662     DWORD color;
9663     DWORD ind;
9664     unsigned i;
9665
9666     const DWORD shader_code[] =
9667     {
9668         0xfffe0101,                                     /* vs_1_1 */
9669         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9670         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9671         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9672         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9673         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9674         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9675         0x0000ffff
9676     };
9677
9678     const float quad[][3] =
9679     {
9680         {-0.5f, -0.5f,  1.1f}, /*0 */
9681         {-0.5f,  0.5f,  1.1f}, /*1 */
9682         { 0.5f, -0.5f,  1.1f}, /*2 */
9683         { 0.5f,  0.5f,  1.1f}, /*3 */
9684     };
9685
9686     const float vertcolor[][4] =
9687     {
9688         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9689         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9690         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9691         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9692     };
9693
9694     /* 4 position for 4 instances */
9695     const float instancepos[][3] =
9696     {
9697         {-0.6f,-0.6f, 0.0f},
9698         { 0.6f,-0.6f, 0.0f},
9699         { 0.6f, 0.6f, 0.0f},
9700         {-0.6f, 0.6f, 0.0f},
9701     };
9702
9703     short indices[] = {0, 1, 2, 1, 2, 3};
9704
9705     D3DVERTEXELEMENT9 decl[] =
9706     {
9707         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9708         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9709         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9710         D3DDECL_END()
9711     };
9712
9713     /* set the default value because it isn't done in wine? */
9714     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9715     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9716
9717     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9718     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9719     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9720
9721     /* check wrong cases */
9722     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9723     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9724     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9725     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9726     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9727     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9728     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9729     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9730     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9731     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9732     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9733     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9734     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9735     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9736     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9737     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9738     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9739     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9740     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9741     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9742
9743     /* set the default value back */
9744     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9745     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9746
9747     /* create all VertexBuffers*/
9748     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9749     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9750     if(!vb) {
9751         skip("Failed to create a vertex buffer\n");
9752         return;
9753     }
9754     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9755     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9756     if(!vb2) {
9757         skip("Failed to create a vertex buffer\n");
9758         goto out;
9759     }
9760     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9761     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9762     if(!vb3) {
9763         skip("Failed to create a vertex buffer\n");
9764         goto out;
9765     }
9766
9767     /* create IndexBuffer*/
9768     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9769     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9770     if(!ib) {
9771         skip("Failed to create a index buffer\n");
9772         goto out;
9773     }
9774
9775     /* copy all Buffers (Vertex + Index)*/
9776     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9777     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9778     memcpy(data, quad, sizeof(quad));
9779     hr = IDirect3DVertexBuffer9_Unlock(vb);
9780     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9781     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9782     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9783     memcpy(data, vertcolor, sizeof(vertcolor));
9784     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9785     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9786     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9787     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9788     memcpy(data, instancepos, sizeof(instancepos));
9789     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9790     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9791     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9792     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9793     memcpy(data, indices, sizeof(indices));
9794     hr = IDirect3DIndexBuffer9_Unlock(ib);
9795     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9796
9797     /* create VertexShader */
9798     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9799     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9800     if(!shader) {
9801         skip("Failed to create a vetex shader\n");
9802         goto out;
9803     }
9804
9805     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9806     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9807
9808     hr = IDirect3DDevice9_SetIndices(device, ib);
9809     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9810
9811     /* run all tests */
9812     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9813     {
9814         struct testdata act = testcases[i];
9815         decl[0].Stream = act.strVertex;
9816         decl[1].Stream = act.strColor;
9817         decl[2].Stream = act.strInstance;
9818         /* create VertexDeclarations */
9819         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9820         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9821
9822         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9823         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9824
9825         hr = IDirect3DDevice9_BeginScene(device);
9826         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9827         if(SUCCEEDED(hr))
9828         {
9829             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9830             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9831
9832             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9833             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9834             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9835             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9836
9837             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9838             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9839             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9840             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9841
9842             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9843             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9844             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9845             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9846
9847             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9848             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9849             hr = IDirect3DDevice9_EndScene(device);
9850             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9851
9852             /* set all StreamSource && StreamSourceFreq back to default */
9853             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9854             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9855             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9856             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9857             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9858             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9859             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9860             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9861             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9862             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9863             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9864             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9865         }
9866
9867         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9868         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9869
9870         color = getPixelColor(device, 160, 360);
9871         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9872         color = getPixelColor(device, 480, 360);
9873         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9874         color = getPixelColor(device, 480, 120);
9875         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9876         color = getPixelColor(device, 160, 120);
9877         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9878
9879         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9880         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9881     }
9882
9883     hr = IDirect3DDevice9_SetIndices(device, NULL);
9884     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9885
9886 out:
9887     if(vb) IDirect3DVertexBuffer9_Release(vb);
9888     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9889     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9890     if(ib)IDirect3DIndexBuffer9_Release(ib);
9891     if(shader)IDirect3DVertexShader9_Release(shader);
9892 }
9893
9894 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9895     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9896     IDirect3DTexture9 *dsttex = NULL;
9897     HRESULT hr;
9898     DWORD color;
9899     D3DRECT r1 = {0,  0,  50,  50 };
9900     D3DRECT r2 = {50, 0,  100, 50 };
9901     D3DRECT r3 = {50, 50, 100, 100};
9902     D3DRECT r4 = {0,  50,  50, 100};
9903     const float quad[] = {
9904         -1.0,   -1.0,   0.1,    0.0,    0.0,
9905          1.0,   -1.0,   0.1,    1.0,    0.0,
9906         -1.0,    1.0,   0.1,    0.0,    1.0,
9907          1.0,    1.0,   0.1,    1.0,    1.0,
9908     };
9909
9910     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9911     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9912
9913     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9914     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9915     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9916     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9917
9918     if(!src || !dsttex) {
9919         skip("One or more test resources could not be created\n");
9920         goto cleanup;
9921     }
9922
9923     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9924     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9925
9926     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9927     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9928
9929     /* Clear the StretchRect destination for debugging */
9930     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9931     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9932     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9933     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9934
9935     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9936     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9937
9938     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9939     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9940     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9941     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9942     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9943     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9944     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9945     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9946
9947     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9948      * the target -> texture GL blit path
9949      */
9950     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9951     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9952     IDirect3DSurface9_Release(dst);
9953
9954     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9955     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9956
9957     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9958     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9959     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9960     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9961     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9962     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9963     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9964     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9965
9966     hr = IDirect3DDevice9_BeginScene(device);
9967     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9968     if(SUCCEEDED(hr)) {
9969         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9970         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9971         hr = IDirect3DDevice9_EndScene(device);
9972         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9973     }
9974
9975     color = getPixelColor(device, 160, 360);
9976     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9977     color = getPixelColor(device, 480, 360);
9978     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9979     color = getPixelColor(device, 480, 120);
9980     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9981     color = getPixelColor(device, 160, 120);
9982     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9983     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9984     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9985
9986     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9987     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9988     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9989     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9990
9991 cleanup:
9992     if(src) IDirect3DSurface9_Release(src);
9993     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9994     if(dsttex) IDirect3DTexture9_Release(dsttex);
9995 }
9996
9997 static void texop_test(IDirect3DDevice9 *device)
9998 {
9999     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
10000     IDirect3DTexture9 *texture = NULL;
10001     D3DLOCKED_RECT locked_rect;
10002     D3DCOLOR color;
10003     D3DCAPS9 caps;
10004     HRESULT hr;
10005     unsigned i;
10006
10007     static const struct {
10008         float x, y, z;
10009         float s, t;
10010         D3DCOLOR diffuse;
10011     } quad[] = {
10012         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10013         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10014         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10015         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
10016     };
10017
10018     static const D3DVERTEXELEMENT9 decl_elements[] = {
10019         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10020         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
10021         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
10022         D3DDECL_END()
10023     };
10024
10025     static const struct {
10026         D3DTEXTUREOP op;
10027         const char *name;
10028         DWORD caps_flag;
10029         D3DCOLOR result;
10030     } test_data[] = {
10031         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10032         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
10033         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
10034         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
10035         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10036         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10037         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
10038         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10039         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10040         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10041         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10042         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
10043         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
10044         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10045         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10046         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
10047         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
10048         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10049         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
10050         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
10051         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
10052         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
10053         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
10054     };
10055
10056     memset(&caps, 0, sizeof(caps));
10057     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10058     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10059
10060     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
10061     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
10062     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
10063     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
10064
10065     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10066     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10067     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10068     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10069     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
10070     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10071     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10072     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10073     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10074
10075     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
10076     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10077     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10078     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10079     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10080     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10081
10082     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10083     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10084
10085     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10086     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10087     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
10088     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10089     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
10090     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10091
10092     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10093     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10094
10095     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
10096     {
10097         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
10098         {
10099             skip("tex operation %s not supported\n", test_data[i].name);
10100             continue;
10101         }
10102
10103         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
10104         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
10105
10106         hr = IDirect3DDevice9_BeginScene(device);
10107         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10108
10109         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10110         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10111
10112         hr = IDirect3DDevice9_EndScene(device);
10113         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10114
10115         color = getPixelColor(device, 320, 240);
10116         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
10117                 test_data[i].name, color, test_data[i].result);
10118
10119         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10120         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10121     }
10122
10123     if (texture) IDirect3DTexture9_Release(texture);
10124     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
10125 }
10126
10127 static void yuv_color_test(IDirect3DDevice9 *device) {
10128     HRESULT hr;
10129     IDirect3DSurface9 *surface = NULL, *target = NULL;
10130     unsigned int fmt, i;
10131     D3DFORMAT format;
10132     const char *fmt_string;
10133     D3DLOCKED_RECT lr;
10134     IDirect3D9 *d3d;
10135     HRESULT color;
10136     DWORD ref_color_left, ref_color_right;
10137
10138     struct {
10139         DWORD in;           /* The input color */
10140         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
10141         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
10142         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
10143         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
10144     } test_data[] = {
10145     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
10146      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
10147      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
10148      * that
10149      */
10150       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
10151       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
10152       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
10153       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
10154       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
10155       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
10156       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
10157       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
10158       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
10159       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
10160       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
10161       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
10162       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
10163       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
10164
10165       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
10166       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
10167       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
10168       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
10169     };
10170
10171     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
10172     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
10173     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
10174     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
10175
10176     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
10177     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10178
10179     for(fmt = 0; fmt < 2; fmt++) {
10180         if(fmt == 0) {
10181             format = D3DFMT_UYVY;
10182             fmt_string = "D3DFMT_UYVY";
10183         } else {
10184             format = D3DFMT_YUY2;
10185             fmt_string = "D3DFMT_YUY2";
10186         }
10187
10188         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
10189                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
10190                        */
10191         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
10192                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
10193             skip("%s is not supported\n", fmt_string);
10194             continue;
10195         }
10196
10197         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
10198         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
10199         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
10200
10201         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
10202             if(fmt == 0) {
10203                 ref_color_left = test_data[i].uyvy_left;
10204                 ref_color_right = test_data[i].uyvy_right;
10205             } else {
10206                 ref_color_left = test_data[i].yuy2_left;
10207                 ref_color_right = test_data[i].yuy2_right;
10208             }
10209
10210             memset(&lr, 0, sizeof(lr));
10211             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
10212             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
10213             *((DWORD *) lr.pBits) = test_data[i].in;
10214             hr = IDirect3DSurface9_UnlockRect(surface);
10215             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10216
10217             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10218             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10219             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10220             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10221
10222             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10223              * prevent running into precision problems, read a far left and far right pixel. In the future we may
10224              * want to add tests for the filtered pixels as well.
10225              *
10226              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10227              * differently, so we need a max diff of 16
10228              */
10229             color = getPixelColor(device, 40, 240);
10230
10231             /* Newer versions of the Nvidia Windows driver mix up the U and V channels, breaking all the tests
10232              * where U != V. Skip the entire test if this bug in this case
10233              */
10234             if (broken(test_data[i].in == 0xff000000 && color == 0x00008800 && format == D3DFMT_UYVY))
10235             {
10236                 skip("Nvidia channel confusion bug detected, skipping YUV tests\n");
10237                 IDirect3DSurface9_Release(surface);
10238                 goto out;
10239             }
10240
10241             ok(color_match(color, ref_color_left, 18),
10242                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10243                test_data[i].in, color, ref_color_left, fmt_string);
10244             color = getPixelColor(device, 600, 240);
10245             ok(color_match(color, ref_color_right, 18),
10246                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10247                test_data[i].in, color, ref_color_right, fmt_string);
10248             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10249             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10250         }
10251         IDirect3DSurface9_Release(surface);
10252     }
10253
10254 out:
10255     IDirect3DSurface9_Release(target);
10256     IDirect3D9_Release(d3d);
10257 }
10258
10259 static void texop_range_test(IDirect3DDevice9 *device)
10260 {
10261     static const struct {
10262         float x, y, z;
10263         D3DCOLOR diffuse;
10264     } quad[] = {
10265         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10266         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10267         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10268         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10269     };
10270     HRESULT hr;
10271     IDirect3DTexture9 *texture;
10272     D3DLOCKED_RECT locked_rect;
10273     D3DCAPS9 caps;
10274     DWORD color;
10275
10276     /* We need ADD and SUBTRACT operations */
10277     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10278     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10279     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10280         skip("D3DTOP_ADD is not supported, skipping value range test\n");
10281         return;
10282     }
10283     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10284         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10285         return;
10286     }
10287
10288     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10289     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10290     /* Stage 1: result = diffuse(=1.0) + diffuse
10291      * stage 2: result = result - tfactor(= 0.5)
10292      */
10293     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10294     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10295     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10296     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10297     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10298     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10299     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10300     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10301     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10302     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10303     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10304     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10305     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10306     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10307
10308     hr = IDirect3DDevice9_BeginScene(device);
10309     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10310     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10311     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10312     hr = IDirect3DDevice9_EndScene(device);
10313     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10314
10315     color = getPixelColor(device, 320, 240);
10316     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10317        color);
10318     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10319     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10320
10321     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10322     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10323     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10324     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10325     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10326     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10327     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10328     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10329     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10330
10331     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10332      * stage 2: result = result + diffuse(1.0)
10333      */
10334     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10335     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10336     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10337     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10338     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10339     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10340     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10341     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10342     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10343     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10344     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10345     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10346     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10347     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10348
10349     hr = IDirect3DDevice9_BeginScene(device);
10350     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10351     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10352     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10353     hr = IDirect3DDevice9_EndScene(device);
10354     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10355
10356     color = getPixelColor(device, 320, 240);
10357     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10358        color);
10359     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10360     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10361
10362     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10363     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10364     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10365     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10366     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10367     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10368     IDirect3DTexture9_Release(texture);
10369 }
10370
10371 static void alphareplicate_test(IDirect3DDevice9 *device) {
10372     struct vertex quad[] = {
10373         { -1.0,    -1.0,    0.1,    0x80ff00ff },
10374         {  1.0,    -1.0,    0.1,    0x80ff00ff },
10375         { -1.0,     1.0,    0.1,    0x80ff00ff },
10376         {  1.0,     1.0,    0.1,    0x80ff00ff },
10377     };
10378     HRESULT hr;
10379     DWORD color;
10380
10381     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10382     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10383
10384     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10385     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10386
10387     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10388     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10389     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10390     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10391
10392     hr = IDirect3DDevice9_BeginScene(device);
10393     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10394     if(SUCCEEDED(hr)) {
10395         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10396         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10397         hr = IDirect3DDevice9_EndScene(device);
10398         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10399     }
10400
10401     color = getPixelColor(device, 320, 240);
10402     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10403        color);
10404     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10405     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10406
10407     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10408     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10409
10410 }
10411
10412 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10413     HRESULT hr;
10414     D3DCAPS9 caps;
10415     DWORD color;
10416     struct vertex quad[] = {
10417         { -1.0,    -1.0,    0.1,    0x408080c0 },
10418         {  1.0,    -1.0,    0.1,    0x408080c0 },
10419         { -1.0,     1.0,    0.1,    0x408080c0 },
10420         {  1.0,     1.0,    0.1,    0x408080c0 },
10421     };
10422
10423     memset(&caps, 0, sizeof(caps));
10424     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10425     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10426     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10427         skip("D3DTOP_DOTPRODUCT3 not supported\n");
10428         return;
10429     }
10430
10431     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10432     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10433
10434     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10435     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10436
10437     /* dp3_x4 r0, diffuse_bias, tfactor_bias
10438      * mov r0.a, diffuse.a
10439      * mov r0, r0.a
10440      *
10441      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10442      * 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
10443      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10444      */
10445     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10446     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10447     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10448     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10449     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10450     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10451     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10452     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10453     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10454     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10455     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10456     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10457     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10458     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10459     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10460     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10461     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10462     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10463
10464     hr = IDirect3DDevice9_BeginScene(device);
10465     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10466     if(SUCCEEDED(hr)) {
10467         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10468         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10469         hr = IDirect3DDevice9_EndScene(device);
10470         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10471     }
10472
10473     color = getPixelColor(device, 320, 240);
10474     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10475        color);
10476     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10477     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10478
10479     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10480     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10481     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10482     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10483     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10484     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10485 }
10486
10487 static void zwriteenable_test(IDirect3DDevice9 *device) {
10488     HRESULT hr;
10489     DWORD color;
10490     struct vertex quad1[] = {
10491         { -1.0,  -1.0,  0.1,    0x00ff0000},
10492         { -1.0,   1.0,  0.1,    0x00ff0000},
10493         {  1.0,  -1.0,  0.1,    0x00ff0000},
10494         {  1.0,   1.0,  0.1,    0x00ff0000},
10495     };
10496     struct vertex quad2[] = {
10497         { -1.0,  -1.0,  0.9,    0x0000ff00},
10498         { -1.0,   1.0,  0.9,    0x0000ff00},
10499         {  1.0,  -1.0,  0.9,    0x0000ff00},
10500         {  1.0,   1.0,  0.9,    0x0000ff00},
10501     };
10502
10503     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10504     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10505
10506     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10507     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10508     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10509     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10510     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10511     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10512     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10513     ok(hr == D3D_OK, "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         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10519          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10520          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10521          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10522          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10523          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10524          */
10525         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10526         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10527         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10528         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10529         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10530         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10531
10532         hr = IDirect3DDevice9_EndScene(device);
10533         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10534     }
10535
10536     color = getPixelColor(device, 320, 240);
10537     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10538        color);
10539     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10540     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10541
10542     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10543     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10544 }
10545
10546 static void alphatest_test(IDirect3DDevice9 *device) {
10547 #define ALPHATEST_PASSED 0x0000ff00
10548 #define ALPHATEST_FAILED 0x00ff0000
10549     struct {
10550         D3DCMPFUNC  func;
10551         DWORD       color_less;
10552         DWORD       color_equal;
10553         DWORD       color_greater;
10554     } testdata[] = {
10555         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10556         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10557         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10558         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10559         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10560         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10561         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10562         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10563     };
10564     unsigned int i, j;
10565     HRESULT hr;
10566     DWORD color;
10567     struct vertex quad[] = {
10568         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10569         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10570         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10571         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10572     };
10573     D3DCAPS9 caps;
10574
10575     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10576     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10577     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10578     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10579
10580     for(j = 0; j < 2; j++) {
10581         if(j == 1) {
10582             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10583              * the alpha test either for performance reasons(floating point RTs) or to work
10584              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10585              * codepath for ffp and shader in this case, and the test should cover both
10586              */
10587             IDirect3DPixelShader9 *ps;
10588             DWORD shader_code[] = {
10589                 0xffff0101,                                 /* ps_1_1           */
10590                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10591                 0x0000ffff                                  /* end              */
10592             };
10593             memset(&caps, 0, sizeof(caps));
10594             hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10595             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10596             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10597                 break;
10598             }
10599
10600             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10601             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10602             hr = IDirect3DDevice9_SetPixelShader(device, ps);
10603             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10604             IDirect3DPixelShader9_Release(ps);
10605         }
10606
10607         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10608             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10609             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10610
10611             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10612             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10613             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10614             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10615             hr = IDirect3DDevice9_BeginScene(device);
10616             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10617             if(SUCCEEDED(hr)) {
10618                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10619                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10620                 hr = IDirect3DDevice9_EndScene(device);
10621                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10622             }
10623             color = getPixelColor(device, 320, 240);
10624             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10625             color, testdata[i].color_less, testdata[i].func);
10626             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10627             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10628
10629             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10630             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10631             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10632             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10633             hr = IDirect3DDevice9_BeginScene(device);
10634             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10635             if(SUCCEEDED(hr)) {
10636                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10637                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10638                 hr = IDirect3DDevice9_EndScene(device);
10639                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10640             }
10641             color = getPixelColor(device, 320, 240);
10642             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10643             color, testdata[i].color_equal, testdata[i].func);
10644             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10645             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10646
10647             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10648             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10649             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10650             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10651             hr = IDirect3DDevice9_BeginScene(device);
10652             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10653             if(SUCCEEDED(hr)) {
10654                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10655                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10656                 hr = IDirect3DDevice9_EndScene(device);
10657                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10658             }
10659             color = getPixelColor(device, 320, 240);
10660             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10661             color, testdata[i].color_greater, testdata[i].func);
10662             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10663             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10664         }
10665     }
10666
10667     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10668     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10669     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10670     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10671 }
10672
10673 static void sincos_test(IDirect3DDevice9 *device) {
10674     const DWORD sin_shader_code[] = {
10675         0xfffe0200,                                                                 /* vs_2_0                       */
10676         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10677         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10678         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10679         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10680         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10681         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10682         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10683         0x0000ffff                                                                  /* end                          */
10684     };
10685     const DWORD cos_shader_code[] = {
10686         0xfffe0200,                                                                 /* vs_2_0                       */
10687         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10688         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10689         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10690         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10691         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10692         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10693         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10694         0x0000ffff                                                                  /* end                          */
10695     };
10696     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10697     HRESULT hr;
10698     struct {
10699         float x, y, z;
10700     } data[1280];
10701     unsigned int i;
10702     float sincosc1[4] = {D3DSINCOSCONST1};
10703     float sincosc2[4] = {D3DSINCOSCONST2};
10704
10705     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10706     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10707
10708     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10709     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10710     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10711     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10712     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10713     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10714     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10715     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10716     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10717     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10718
10719     /* Generate a point from -1 to 1 every 0.5 pixels */
10720     for(i = 0; i < 1280; i++) {
10721         data[i].x = (-640.0 + i) / 640.0;
10722         data[i].y = 0.0;
10723         data[i].z = 0.1;
10724     }
10725
10726     hr = IDirect3DDevice9_BeginScene(device);
10727     if(SUCCEEDED(hr)) {
10728         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10729         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10730         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10731         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10732
10733         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10734         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10735         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10736         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10737
10738         hr = IDirect3DDevice9_EndScene(device);
10739         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10740     }
10741     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10742     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10743     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10744
10745     IDirect3DDevice9_SetVertexShader(device, NULL);
10746     IDirect3DVertexShader9_Release(sin_shader);
10747     IDirect3DVertexShader9_Release(cos_shader);
10748 }
10749
10750 static void loop_index_test(IDirect3DDevice9 *device) {
10751     const DWORD shader_code[] = {
10752         0xfffe0200,                                                 /* vs_2_0                   */
10753         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10754         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10755         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10756         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10757         0x0000001d,                                                 /* endloop                  */
10758         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10759         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10760         0x0000ffff                                                  /* END                      */
10761     };
10762     IDirect3DVertexShader9 *shader;
10763     HRESULT hr;
10764     DWORD color;
10765     const float quad[] = {
10766         -1.0,   -1.0,   0.1,
10767          1.0,   -1.0,   0.1,
10768         -1.0,    1.0,   0.1,
10769          1.0,    1.0,   0.1
10770     };
10771     const float zero[4] = {0, 0, 0, 0};
10772     const float one[4] = {1, 1, 1, 1};
10773     int i0[4] = {2, 10, -3, 0};
10774     float values[4];
10775
10776     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10777     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10778     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10779     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10780     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10781     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10782     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10783     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10784
10785     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10786     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10787     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10788     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10789     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10790     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10791     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10792     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10793     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10794     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10795     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10796     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10797     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10798     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10799     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10800     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10801     values[0] = 1.0;
10802     values[1] = 1.0;
10803     values[2] = 0.0;
10804     values[3] = 0.0;
10805     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10806     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10807     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10808     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10809     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10810     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10811     values[0] = -1.0;
10812     values[1] = 0.0;
10813     values[2] = 0.0;
10814     values[3] = 0.0;
10815     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10816     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10817     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10818     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10819     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10820     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10821     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10822     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10823     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10824     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10825
10826     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10827     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10828
10829     hr = IDirect3DDevice9_BeginScene(device);
10830     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10831     if(SUCCEEDED(hr))
10832     {
10833         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10834         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10835         hr = IDirect3DDevice9_EndScene(device);
10836         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10837     }
10838     color = getPixelColor(device, 320, 240);
10839     ok(color_match(color, 0x0000ff00, 1),
10840        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10841     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10842     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10843
10844     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10845     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10846     IDirect3DVertexShader9_Release(shader);
10847 }
10848
10849 static void sgn_test(IDirect3DDevice9 *device) {
10850     const DWORD shader_code[] = {
10851         0xfffe0200,                                                             /* vs_2_0                       */
10852         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10853         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10854         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10855         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10856         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10857         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10858         0x0000ffff                                                              /* end                          */
10859     };
10860     IDirect3DVertexShader9 *shader;
10861     HRESULT hr;
10862     DWORD color;
10863     const float quad[] = {
10864         -1.0,   -1.0,   0.1,
10865          1.0,   -1.0,   0.1,
10866         -1.0,    1.0,   0.1,
10867          1.0,    1.0,   0.1
10868     };
10869
10870     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10871     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10872     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10873     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10874     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10875     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10876     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10877     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10878
10879     hr = IDirect3DDevice9_BeginScene(device);
10880     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10881     if(SUCCEEDED(hr))
10882     {
10883         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10884         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10885         hr = IDirect3DDevice9_EndScene(device);
10886         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10887     }
10888     color = getPixelColor(device, 320, 240);
10889     ok(color_match(color, 0x008000ff, 1),
10890        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10891     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10892     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10893
10894     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10895     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10896     IDirect3DVertexShader9_Release(shader);
10897 }
10898
10899 static void viewport_test(IDirect3DDevice9 *device) {
10900     HRESULT hr;
10901     DWORD color;
10902     D3DVIEWPORT9 vp, old_vp;
10903     BOOL draw_failed = TRUE;
10904     const float quad[] =
10905     {
10906         -0.5,   -0.5,   0.1,
10907          0.5,   -0.5,   0.1,
10908         -0.5,    0.5,   0.1,
10909          0.5,    0.5,   0.1
10910     };
10911
10912     memset(&old_vp, 0, sizeof(old_vp));
10913     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10914     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10915
10916     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10917     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10918
10919     /* Test a viewport with Width and Height bigger than the surface dimensions
10920      *
10921      * TODO: Test Width < surface.width, but X + Width > surface.width
10922      * TODO: Test Width < surface.width, what happens with the height?
10923      *
10924      * The expected behavior is that the viewport behaves like the "default"
10925      * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
10926      * MinZ = 0.0, MaxZ = 1.0.
10927      *
10928      * Starting with Windows 7 the behavior among driver versions is not
10929      * consistent. The SetViewport call is accepted on all drivers. Some
10930      * drivers(older nvidia ones) refuse to draw and return an error. Newer
10931      * nvidia drivers draw, but use the actual values in the viewport and only
10932      * display the upper left part on the surface.
10933      */
10934     memset(&vp, 0, sizeof(vp));
10935     vp.X = 0;
10936     vp.Y = 0;
10937     vp.Width = 10000;
10938     vp.Height = 10000;
10939     vp.MinZ = 0.0;
10940     vp.MaxZ = 0.0;
10941     hr = IDirect3DDevice9_SetViewport(device, &vp);
10942     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10943
10944     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10945     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10946     hr = IDirect3DDevice9_BeginScene(device);
10947     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10948     if(SUCCEEDED(hr))
10949     {
10950         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10951         ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10952         draw_failed = FAILED(hr);
10953         hr = IDirect3DDevice9_EndScene(device);
10954         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10955     }
10956
10957     if(!draw_failed)
10958     {
10959         color = getPixelColor(device, 158, 118);
10960         ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10961         color = getPixelColor(device, 162, 118);
10962         ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10963         color = getPixelColor(device, 158, 122);
10964         ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10965         color = getPixelColor(device, 162, 122);
10966         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
10967
10968         color = getPixelColor(device, 478, 358);
10969         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
10970         color = getPixelColor(device, 482, 358);
10971         ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10972         color = getPixelColor(device, 478, 362);
10973         ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10974         color = getPixelColor(device, 482, 362);
10975         ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10976     }
10977
10978     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10979     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10980
10981     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10982     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10983 }
10984
10985 /* This test tests depth clamping / clipping behaviour:
10986  *   - With software vertex processing, depth values are clamped to the
10987  *     minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
10988  *     when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
10989  *     same as regular vertices here.
10990  *   - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
10991  *     Normal vertices are always clipped. Pretransformed vertices are
10992  *     clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
10993  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10994  */
10995 static void depth_clamp_test(IDirect3DDevice9 *device)
10996 {
10997     const struct tvertex quad1[] =
10998     {
10999         {  0.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
11000         {640.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
11001         {  0.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
11002         {640.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
11003     };
11004     const struct tvertex quad2[] =
11005     {
11006         {  0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
11007         {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
11008         {  0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
11009         {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
11010     };
11011     const struct tvertex quad3[] =
11012     {
11013         {112.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
11014         {208.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
11015         {112.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
11016         {208.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
11017     };
11018     const struct tvertex quad4[] =
11019     {
11020         { 42.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
11021         {112.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
11022         { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
11023         {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
11024     };
11025     const struct vertex quad5[] =
11026     {
11027         { -0.5f,   0.5f, 10.0f,       0xff14f914},
11028         {  0.5f,   0.5f, 10.0f,       0xff14f914},
11029         { -0.5f,  -0.5f, 10.0f,       0xff14f914},
11030         {  0.5f,  -0.5f, 10.0f,       0xff14f914},
11031     };
11032     const struct vertex quad6[] =
11033     {
11034         { -1.0f,   0.5f, 10.0f,      0xfff91414},
11035         {  1.0f,   0.5f, 10.0f,      0xfff91414},
11036         { -1.0f,  0.25f, 10.0f,      0xfff91414},
11037         {  1.0f,  0.25f, 10.0f,      0xfff91414},
11038     };
11039
11040     D3DVIEWPORT9 vp;
11041     D3DCOLOR color;
11042     D3DCAPS9 caps;
11043     HRESULT hr;
11044
11045     vp.X = 0;
11046     vp.Y = 0;
11047     vp.Width = 640;
11048     vp.Height = 480;
11049     vp.MinZ = 0.0;
11050     vp.MaxZ = 7.5;
11051
11052     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11053     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11054
11055     hr = IDirect3DDevice9_SetViewport(device, &vp);
11056     if(FAILED(hr))
11057     {
11058         /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
11059          * the tests because the 7.5 is just intended to show that it doesn't have
11060          * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
11061          * viewport and continue.
11062          */
11063         ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
11064         vp.MaxZ = 1.0;
11065         hr = IDirect3DDevice9_SetViewport(device, &vp);
11066     }
11067     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11068
11069     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
11070     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11071
11072     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
11073     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11074     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11075     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11076     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11077     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11078     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11079     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11080
11081     hr = IDirect3DDevice9_BeginScene(device);
11082     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11083
11084     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11085     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11086
11087     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11088     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11089     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11090     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11091
11092     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11093     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11094
11095     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11096     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11097     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
11098     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11099
11100     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
11101     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11102
11103     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11104     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11105
11106     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
11107     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11108
11109     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11110     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11111
11112     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
11113     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11114
11115     hr = IDirect3DDevice9_EndScene(device);
11116     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11117
11118     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
11119     {
11120         color = getPixelColor(device, 75, 75);
11121         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11122         color = getPixelColor(device, 150, 150);
11123         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11124         color = getPixelColor(device, 320, 240);
11125         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11126         color = getPixelColor(device, 320, 330);
11127         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11128         color = getPixelColor(device, 320, 330);
11129         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11130     }
11131     else
11132     {
11133         color = getPixelColor(device, 75, 75);
11134         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11135         color = getPixelColor(device, 150, 150);
11136         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11137         color = getPixelColor(device, 320, 240);
11138         ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11139         color = getPixelColor(device, 320, 330);
11140         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11141         color = getPixelColor(device, 320, 330);
11142         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11143     }
11144
11145     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11146     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11147
11148     vp.MinZ = 0.0;
11149     vp.MaxZ = 1.0;
11150     hr = IDirect3DDevice9_SetViewport(device, &vp);
11151     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11152 }
11153
11154 static void depth_bounds_test(IDirect3DDevice9 *device)
11155 {
11156     const struct tvertex quad1[] =
11157     {
11158         {    0,    0, 0.0f, 1, 0xfff9e814},
11159         {  640,    0, 0.0f, 1, 0xfff9e814},
11160         {    0,  480, 1.0f, 1, 0xfff9e814},
11161         {  640,  480, 1.0f, 1, 0xfff9e814},
11162     };
11163     const struct tvertex quad2[] =
11164     {
11165         {    0,    0,  0.6f, 1, 0xff002b7f},
11166         {  640,    0,  0.6f, 1, 0xff002b7f},
11167         {    0,  480,  0.6f, 1, 0xff002b7f},
11168         {  640,  480,  0.6f, 1, 0xff002b7f},
11169     };
11170     const struct tvertex quad3[] =
11171     {
11172         {    0,  100, 0.6f, 1, 0xfff91414},
11173         {  640,  100, 0.6f, 1, 0xfff91414},
11174         {    0,  160, 0.6f, 1, 0xfff91414},
11175         {  640,  160, 0.6f, 1, 0xfff91414},
11176     };
11177
11178     union {
11179         DWORD d;
11180         float f;
11181     } tmpvalue;
11182
11183     IDirect3D9 *d3d = NULL;
11184     IDirect3DSurface9 *offscreen_surface = NULL;
11185     D3DCOLOR color;
11186     HRESULT hr;
11187
11188     IDirect3DDevice9_GetDirect3D(device, &d3d);
11189     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11190             0,  D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
11191         skip("No NVDB (depth bounds test) support\n");
11192         IDirect3D9_Release(d3d);
11193         return;
11194     }
11195     IDirect3D9_Release(d3d);
11196
11197     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
11198             MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
11199     ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
11200     if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
11201
11202     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
11203     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11204
11205     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11206     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11207     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
11208     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11209     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11210     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11211     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11212     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11213
11214
11215     hr = IDirect3DDevice9_BeginScene(device);
11216     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11217
11218     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11219     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11220
11221     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11222     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11223
11224     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
11225     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11226
11227     tmpvalue.f = 0.625;
11228     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11229     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11230
11231     tmpvalue.f = 0.75;
11232     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
11233     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11234
11235     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11236     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11237
11238     tmpvalue.f = 0.75;
11239     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11240     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11241
11242     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11243     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11244
11245     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
11246     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11247
11248     hr = IDirect3DDevice9_EndScene(device);
11249     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11250
11251     color = getPixelColor(device, 150, 130);
11252     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11253     color = getPixelColor(device, 150, 200);
11254     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11255     color = getPixelColor(device, 150, 300-5);
11256     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11257     color = getPixelColor(device, 150, 300+5);
11258     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11259     color = getPixelColor(device, 150, 330);
11260     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11261     color = getPixelColor(device, 150, 360-5);
11262     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11263     color = getPixelColor(device, 150, 360+5);
11264     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11265
11266     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11267     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11268 }
11269
11270 static void depth_buffer_test(IDirect3DDevice9 *device)
11271 {
11272     static const struct vertex quad1[] =
11273     {
11274         { -1.0,  1.0, 0.33f, 0xff00ff00},
11275         {  1.0,  1.0, 0.33f, 0xff00ff00},
11276         { -1.0, -1.0, 0.33f, 0xff00ff00},
11277         {  1.0, -1.0, 0.33f, 0xff00ff00},
11278     };
11279     static const struct vertex quad2[] =
11280     {
11281         { -1.0,  1.0, 0.50f, 0xffff00ff},
11282         {  1.0,  1.0, 0.50f, 0xffff00ff},
11283         { -1.0, -1.0, 0.50f, 0xffff00ff},
11284         {  1.0, -1.0, 0.50f, 0xffff00ff},
11285     };
11286     static const struct vertex quad3[] =
11287     {
11288         { -1.0,  1.0, 0.66f, 0xffff0000},
11289         {  1.0,  1.0, 0.66f, 0xffff0000},
11290         { -1.0, -1.0, 0.66f, 0xffff0000},
11291         {  1.0, -1.0, 0.66f, 0xffff0000},
11292     };
11293     static const DWORD expected_colors[4][4] =
11294     {
11295         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11296         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11297         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11298         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11299     };
11300
11301     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
11302     unsigned int i, j;
11303     D3DVIEWPORT9 vp;
11304     D3DCOLOR color;
11305     HRESULT hr;
11306
11307     vp.X = 0;
11308     vp.Y = 0;
11309     vp.Width = 640;
11310     vp.Height = 480;
11311     vp.MinZ = 0.0;
11312     vp.MaxZ = 1.0;
11313
11314     hr = IDirect3DDevice9_SetViewport(device, &vp);
11315     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11316
11317     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11318     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11319     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11320     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11321     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11322     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11323     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11324     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11325     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11326     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11327
11328     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11329     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11330     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
11331             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11332     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11333     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11334             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11335     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11336     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11337             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
11338     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11339
11340     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11341     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11342     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11343     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11344
11345     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11346     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11347     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11348     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11349
11350     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11351     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11352     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11353     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11354
11355     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11356     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11357     hr = IDirect3DDevice9_BeginScene(device);
11358     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11359     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11360     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11361     hr = IDirect3DDevice9_EndScene(device);
11362     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11363
11364     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11365     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11366     IDirect3DSurface9_Release(backbuffer);
11367     IDirect3DSurface9_Release(rt3);
11368     IDirect3DSurface9_Release(rt2);
11369     IDirect3DSurface9_Release(rt1);
11370
11371     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11372     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11373
11374     hr = IDirect3DDevice9_BeginScene(device);
11375     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11376     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11377     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11378     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11379     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11380     hr = IDirect3DDevice9_EndScene(device);
11381     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11382
11383     for (i = 0; i < 4; ++i)
11384     {
11385         for (j = 0; j < 4; ++j)
11386         {
11387             unsigned int x = 80 * ((2 * j) + 1);
11388             unsigned int y = 60 * ((2 * i) + 1);
11389             color = getPixelColor(device, x, y);
11390             ok(color_match(color, expected_colors[i][j], 0),
11391                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11392         }
11393     }
11394
11395     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11396     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11397 }
11398
11399 /* Test that partial depth copies work the way they're supposed to. The clear
11400  * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
11401  * the following draw should only copy back the part that was modified. */
11402 static void depth_buffer2_test(IDirect3DDevice9 *device)
11403 {
11404     static const struct vertex quad[] =
11405     {
11406         { -1.0,  1.0, 0.66f, 0xffff0000},
11407         {  1.0,  1.0, 0.66f, 0xffff0000},
11408         { -1.0, -1.0, 0.66f, 0xffff0000},
11409         {  1.0, -1.0, 0.66f, 0xffff0000},
11410     };
11411
11412     IDirect3DSurface9 *backbuffer, *rt1, *rt2;
11413     unsigned int i, j;
11414     D3DVIEWPORT9 vp;
11415     D3DCOLOR color;
11416     HRESULT hr;
11417
11418     vp.X = 0;
11419     vp.Y = 0;
11420     vp.Width = 640;
11421     vp.Height = 480;
11422     vp.MinZ = 0.0;
11423     vp.MaxZ = 1.0;
11424
11425     hr = IDirect3DDevice9_SetViewport(device, &vp);
11426     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11427
11428     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11429     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11430     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11431     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11432     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11433     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11434     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11435     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11436     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11437     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11438
11439     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11440             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11441     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11442     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11443             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11444     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11445     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11446     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11447
11448     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11449     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11450     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11451     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11452
11453     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11454     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11455     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
11456     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11457
11458     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11459     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11460     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11461     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11462
11463     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11464     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11465     IDirect3DSurface9_Release(backbuffer);
11466     IDirect3DSurface9_Release(rt2);
11467     IDirect3DSurface9_Release(rt1);
11468
11469     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11470     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11471
11472     hr = IDirect3DDevice9_BeginScene(device);
11473     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11474     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11475     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11476     hr = IDirect3DDevice9_EndScene(device);
11477     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11478
11479     for (i = 0; i < 4; ++i)
11480     {
11481         for (j = 0; j < 4; ++j)
11482         {
11483             unsigned int x = 80 * ((2 * j) + 1);
11484             unsigned int y = 60 * ((2 * i) + 1);
11485             color = getPixelColor(device, x, y);
11486             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11487                     "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
11488         }
11489     }
11490
11491     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11492     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11493 }
11494
11495 static void depth_blit_test(IDirect3DDevice9 *device)
11496 {
11497     static const struct vertex quad1[] =
11498     {
11499         { -1.0,  1.0, 0.50f, 0xff00ff00},
11500         {  1.0,  1.0, 0.50f, 0xff00ff00},
11501         { -1.0, -1.0, 0.50f, 0xff00ff00},
11502         {  1.0, -1.0, 0.50f, 0xff00ff00},
11503     };
11504     static const struct vertex quad2[] =
11505     {
11506         { -1.0,  1.0, 0.66f, 0xff0000ff},
11507         {  1.0,  1.0, 0.66f, 0xff0000ff},
11508         { -1.0, -1.0, 0.66f, 0xff0000ff},
11509         {  1.0, -1.0, 0.66f, 0xff0000ff},
11510     };
11511     static const DWORD expected_colors[4][4] =
11512     {
11513         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11514         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11515         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11516         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11517     };
11518
11519     IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
11520     RECT src_rect, dst_rect;
11521     unsigned int i, j;
11522     D3DVIEWPORT9 vp;
11523     D3DCOLOR color;
11524     HRESULT hr;
11525
11526     vp.X = 0;
11527     vp.Y = 0;
11528     vp.Width = 640;
11529     vp.Height = 480;
11530     vp.MinZ = 0.0;
11531     vp.MaxZ = 1.0;
11532
11533     hr = IDirect3DDevice9_SetViewport(device, &vp);
11534     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11535
11536     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11537     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11538     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11539     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11540     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11541     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11542     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11543     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11544     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
11545     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11546
11547     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11548     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11549     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11550     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11551     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11552     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11553     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11554     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11555
11556     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11557     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11558     SetRect(&dst_rect, 0, 0, 480, 360);
11559     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11560     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11561     SetRect(&dst_rect, 0, 0, 320, 240);
11562     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11563     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11564
11565     /* Partial blit. */
11566     SetRect(&src_rect, 0, 0, 320, 240);
11567     SetRect(&dst_rect, 0, 0, 320, 240);
11568     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11569     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11570     /* Flipped. */
11571     SetRect(&src_rect, 0, 0, 640, 480);
11572     SetRect(&dst_rect, 0, 480, 640, 0);
11573     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11574     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11575     /* Full, explicit. */
11576     SetRect(&src_rect, 0, 0, 640, 480);
11577     SetRect(&dst_rect, 0, 0, 640, 480);
11578     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11579     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11580     /* Filtered blit. */
11581     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11582     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11583     /* Depth -> color blit.*/
11584     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11585     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11586     IDirect3DSurface9_Release(backbuffer);
11587     /* Full surface, different sizes */
11588     hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
11589     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11590     hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
11591     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11592
11593     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11594     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11595     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11596     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11597     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11598     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11599     IDirect3DSurface9_Release(ds3);
11600     IDirect3DSurface9_Release(ds2);
11601     IDirect3DSurface9_Release(ds1);
11602
11603     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11604     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11605     hr = IDirect3DDevice9_BeginScene(device);
11606     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11607     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11608     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11609     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11610     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11611     hr = IDirect3DDevice9_EndScene(device);
11612     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11613
11614     for (i = 0; i < 4; ++i)
11615     {
11616         for (j = 0; j < 4; ++j)
11617         {
11618             unsigned int x = 80 * ((2 * j) + 1);
11619             unsigned int y = 60 * ((2 * i) + 1);
11620             color = getPixelColor(device, x, y);
11621             ok(color_match(color, expected_colors[i][j], 0),
11622                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11623         }
11624     }
11625
11626     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11627     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11628 }
11629
11630 static void intz_test(IDirect3DDevice9 *device)
11631 {
11632     static const DWORD ps_code[] =
11633     {
11634         0xffff0200,                                                             /* ps_2_0                       */
11635         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11636         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11637         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11638         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11639         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11640         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11641         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11642         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11643         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
11644         0x0000ffff,                                                             /* end                          */
11645     };
11646     struct
11647     {
11648         float x, y, z;
11649         float s, t, p, q;
11650     }
11651     quad[] =
11652     {
11653         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11654         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11655         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11656         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11657     },
11658     half_quad_1[] =
11659     {
11660         { -1.0f,  0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11661         {  1.0f,  0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11662         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11663         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11664     },
11665     half_quad_2[] =
11666     {
11667         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11668         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11669         { -1.0f,  0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11670         {  1.0f,  0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11671     };
11672     struct
11673     {
11674         UINT x, y;
11675         D3DCOLOR color;
11676     }
11677     expected_colors[] =
11678     {
11679         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11680         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11681         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11682         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11683         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11684         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11685         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11686         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11687     };
11688
11689     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11690     IDirect3DTexture9 *texture;
11691     IDirect3DPixelShader9 *ps;
11692     IDirect3DSurface9 *ds;
11693     IDirect3D9 *d3d9;
11694     D3DCAPS9 caps;
11695     HRESULT hr;
11696     UINT i;
11697
11698     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11699     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11700     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11701     {
11702         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11703         return;
11704     }
11705     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
11706     {
11707         skip("No unconditional NP2 texture support, skipping INTZ test.\n");
11708         return;
11709     }
11710
11711     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11712     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11713
11714     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11715             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11716     if (FAILED(hr))
11717     {
11718         skip("No INTZ support, skipping INTZ test.\n");
11719         return;
11720     }
11721
11722     IDirect3D9_Release(d3d9);
11723
11724     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11725     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11726     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11727     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11728
11729     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11730             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11731     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11732     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11733             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11734     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11735     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11736     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11737
11738     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11739     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11740     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11741     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11742     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11743     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11744     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11745     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11746     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11747     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11748
11749     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11750     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11751     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11752     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11753     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11754     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11755     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11756     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11757     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11758     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11759
11760     /* Render offscreen, using the INTZ texture as depth buffer */
11761     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11762     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11763     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11764     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11765     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11766     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11767     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11768     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11769
11770     /* Setup the depth/stencil surface. */
11771     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11772     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11773
11774     hr = IDirect3DDevice9_BeginScene(device);
11775     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11776     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11777     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11778     hr = IDirect3DDevice9_EndScene(device);
11779     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11780
11781     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11782     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11783     IDirect3DSurface9_Release(ds);
11784     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11785     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11786     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11787     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11788     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11789     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11790
11791     /* Read the depth values back. */
11792     hr = IDirect3DDevice9_BeginScene(device);
11793     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11794     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11795     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11796     hr = IDirect3DDevice9_EndScene(device);
11797     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11798
11799     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11800     {
11801         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11802         ok(color_match(color, expected_colors[i].color, 1),
11803                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11804                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11805     }
11806
11807     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11808     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11809
11810     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11811     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11812     IDirect3DTexture9_Release(texture);
11813
11814     /* Render onscreen while using the INTZ texture as depth buffer */
11815     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11816             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11817     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11818     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11819     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11820     ok(SUCCEEDED(hr), "SetDepthStencilSurface 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_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11839     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11840     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11841     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11842
11843     /* Read the depth values back. */
11844     hr = IDirect3DDevice9_BeginScene(device);
11845     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11846     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11847     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11848     hr = IDirect3DDevice9_EndScene(device);
11849     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11850
11851     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11852     {
11853         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11854         ok(color_match(color, expected_colors[i].color, 1),
11855                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11856                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11857     }
11858
11859     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11860     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11861
11862     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11863     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11864     IDirect3DTexture9_Release(texture);
11865
11866     /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
11867     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11868             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11869     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11870     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11871
11872     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11873     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11874     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11875     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11876     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11877     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11878
11879     /* Setup the depth/stencil surface. */
11880     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11881     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11882
11883     hr = IDirect3DDevice9_BeginScene(device);
11884     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11885     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
11886     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11887     hr = IDirect3DDevice9_EndScene(device);
11888     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11889
11890     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11891     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11892
11893     hr = IDirect3DDevice9_BeginScene(device);
11894     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11895     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
11896     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11897     hr = IDirect3DDevice9_EndScene(device);
11898     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11899
11900     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11901     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11902     IDirect3DSurface9_Release(ds);
11903     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11904     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11905     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11906     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11907
11908     /* Read the depth values back. */
11909     hr = IDirect3DDevice9_BeginScene(device);
11910     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11911     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11912     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11913     hr = IDirect3DDevice9_EndScene(device);
11914     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11915
11916     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11917     {
11918         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11919         ok(color_match(color, expected_colors[i].color, 1),
11920                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11921                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11922     }
11923
11924     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11925     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11926
11927     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11928     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11929     IDirect3DSurface9_Release(original_ds);
11930     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11931     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11932     IDirect3DTexture9_Release(texture);
11933     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11934     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11935     IDirect3DPixelShader9_Release(ps);
11936
11937     IDirect3DSurface9_Release(original_rt);
11938     IDirect3DSurface9_Release(rt);
11939 }
11940
11941 static void shadow_test(IDirect3DDevice9 *device)
11942 {
11943     static const DWORD ps_code[] =
11944     {
11945         0xffff0200,                                                             /* ps_2_0                       */
11946         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11947         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11948         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11949         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11950         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11951         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11952         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11953         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11954         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11955         0x0000ffff,                                                             /* end                          */
11956     };
11957     struct
11958     {
11959         D3DFORMAT format;
11960         const char *name;
11961     }
11962     formats[] =
11963     {
11964         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
11965         {D3DFMT_D32,            "D3DFMT_D32"},
11966         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
11967         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
11968         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
11969         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
11970         {D3DFMT_D16,            "D3DFMT_D16"},
11971         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
11972         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
11973     };
11974     struct
11975     {
11976         float x, y, z;
11977         float s, t, p, q;
11978     }
11979     quad[] =
11980     {
11981         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11982         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11983         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11984         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11985     };
11986     struct
11987     {
11988         UINT x, y;
11989         D3DCOLOR color;
11990     }
11991     expected_colors[] =
11992     {
11993         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11994         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11995         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11996         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11997         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11998         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11999         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12000         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12001     };
12002
12003     IDirect3DSurface9 *original_ds, *original_rt, *rt;
12004     IDirect3DPixelShader9 *ps;
12005     IDirect3D9 *d3d9;
12006     D3DCAPS9 caps;
12007     HRESULT hr;
12008     UINT i;
12009
12010     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12011     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12012     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
12013     {
12014         skip("No pixel shader 2.0 support, skipping shadow test.\n");
12015         return;
12016     }
12017
12018     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
12019     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12020     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12021     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12022     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
12023     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
12024
12025     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
12026             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12027     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12028     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12029     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12030
12031     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
12032     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12033     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12034     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12035     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
12036     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12037     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12038     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12039     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12040     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12041
12042     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
12043     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12044     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
12045     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12046     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
12047     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12048     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
12049     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12050     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12051     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12052
12053     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
12054     {
12055         D3DFORMAT format = formats[i].format;
12056         IDirect3DTexture9 *texture;
12057         IDirect3DSurface9 *ds;
12058         unsigned int j;
12059
12060         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12061                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
12062         if (FAILED(hr)) continue;
12063
12064         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
12065                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
12066         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12067
12068         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
12069         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12070
12071         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12072         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12073
12074         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12075         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12076
12077         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12078         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12079
12080         /* Setup the depth/stencil surface. */
12081         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
12082         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12083
12084         hr = IDirect3DDevice9_BeginScene(device);
12085         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12086         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12087         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12088         hr = IDirect3DDevice9_EndScene(device);
12089         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12090
12091         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
12092         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12093         IDirect3DSurface9_Release(ds);
12094
12095         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12096         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12097
12098         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12099         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12100
12101         hr = IDirect3DDevice9_SetPixelShader(device, ps);
12102         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12103
12104         /* Do the actual shadow mapping. */
12105         hr = IDirect3DDevice9_BeginScene(device);
12106         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12107         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12108         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12109         hr = IDirect3DDevice9_EndScene(device);
12110         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12111
12112         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12113         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12114         IDirect3DTexture9_Release(texture);
12115
12116         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
12117         {
12118             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
12119             ok(color_match(color, expected_colors[j].color, 0),
12120                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
12121                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
12122                     formats[i].name, color);
12123         }
12124
12125         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12126         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12127     }
12128
12129     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12130     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12131     IDirect3DPixelShader9_Release(ps);
12132
12133     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
12134     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12135     IDirect3DSurface9_Release(original_ds);
12136
12137     IDirect3DSurface9_Release(original_rt);
12138     IDirect3DSurface9_Release(rt);
12139
12140     IDirect3D9_Release(d3d9);
12141 }
12142
12143 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
12144 {
12145     const struct vertex quad1[] =
12146     {
12147         {-1.0f, -1.0f, 0.0f, 0xfff9e814},
12148         { 1.0f, -1.0f, 0.0f, 0xfff9e814},
12149         {-1.0f,  1.0f, 0.0f, 0xfff9e814},
12150         { 1.0f,  1.0f, 0.0f, 0xfff9e814},
12151     };
12152     const struct vertex quad2[] =
12153     {
12154         {-1.0f, -1.0f, 0.0f, 0xff002b7f},
12155         { 1.0f, -1.0f, 0.0f, 0xff002b7f},
12156         {-1.0f,  1.0f, 0.0f, 0xff002b7f},
12157         { 1.0f,  1.0f, 0.0f, 0xff002b7f},
12158     };
12159     D3DCOLOR color;
12160     HRESULT hr;
12161
12162     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
12163     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12164
12165     hr = IDirect3DDevice9_BeginScene(device);
12166     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12167
12168     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12169     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12170
12171     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12172     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12173     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12174     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12175
12176     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
12177     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12178     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12179     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12180
12181     hr = IDirect3DDevice9_EndScene(device);
12182     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12183
12184     color = getPixelColor(device, 1, 240);
12185     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12186     color = getPixelColor(device, 638, 240);
12187     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12188
12189     color = getPixelColor(device, 1, 241);
12190     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12191     color = getPixelColor(device, 638, 241);
12192     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12193 }
12194
12195 static void clip_planes_test(IDirect3DDevice9 *device)
12196 {
12197     const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
12198
12199     const DWORD shader_code[] = {
12200         0xfffe0200, /* vs_2_0 */
12201         0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12202         0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
12203         0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12204         0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
12205         0x0000ffff /* end */
12206     };
12207     IDirect3DVertexShader9 *shader;
12208
12209     IDirect3DTexture9 *offscreen = NULL;
12210     IDirect3DSurface9 *offscreen_surface, *original_rt;
12211     HRESULT hr;
12212
12213     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12214     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12215
12216     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12217     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12218     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12219     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12220     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12221     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12222     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
12223     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12224
12225     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12226     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12227     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12228     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
12229
12230     IDirect3DDevice9_SetClipPlane(device, 0, plane0);
12231
12232     clip_planes(device, "Onscreen FFP");
12233
12234     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
12235     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12236     hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
12237     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12238     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12239     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12240
12241     clip_planes(device, "Offscreen FFP");
12242
12243     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12244     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12245
12246     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12247     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
12248     hr = IDirect3DDevice9_SetVertexShader(device, shader);
12249     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
12250
12251     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12252     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12253
12254     clip_planes(device, "Onscreen vertex shader");
12255
12256     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12257     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12258
12259     clip_planes(device, "Offscreen vertex shader");
12260
12261     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12262     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12263
12264     IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12265     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12266     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12267     IDirect3DVertexShader9_Release(shader);
12268     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12269     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12270     IDirect3DSurface9_Release(original_rt);
12271     IDirect3DSurface9_Release(offscreen_surface);
12272     IDirect3DTexture9_Release(offscreen);
12273 }
12274
12275 static void fp_special_test(IDirect3DDevice9 *device)
12276 {
12277     static const DWORD vs_header[] =
12278     {
12279         0xfffe0200,                                                             /* vs_2_0                       */
12280         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
12281         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
12282         0x0200001f, 0x80000005, 0x900f0001,                                     /* dcl_texcoord0 v1             */
12283     };
12284
12285     static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001};         /* log r0.x, v1.x               */
12286     static const DWORD vs_pow[] =
12287             {0x03000020, 0x80010000, 0x90000001, 0x90000001};                   /* pow r0.x, v1.x, v1.x         */
12288     static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001};         /* nrm r0.xyz, v1.x             */
12289     static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001};        /* rcp r0.x, v1.x               */
12290     static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001};        /* rcp r0.x, -v1.x              */
12291     static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001};        /* rsq r0.x, v1.x               */
12292     static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001};        /* rsq r0.x, -v1.x              */
12293     static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001,          /* lit r0, v1.xxxx              */
12294             0x02000001, 0x80010000, 0x80aa0000};                                /* mov r0.x, v0.z               */
12295
12296     static const DWORD vs_footer[] =
12297     {
12298         0x03000005, 0x80020000, 0x80000000, 0xa0ff0000,                         /* mul r0.y, r0.x, c0.w         */
12299         0x0300000d, 0x80040000, 0x80000000, 0x80550000,                         /* sge r0.z, r0.x, r0.y         */
12300         0x0300000d, 0x80020000, 0x80e40000, 0x80000000,                         /* sge r0.y, r0, r0.x           */
12301         0x03000005, 0x80040000, 0x80550000, 0x80e40000,                         /* mul r0.z, r0.y, r0           */
12302         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
12303         0x0300000c, 0x80020000, 0x80000000, 0x80000000,                         /* slt r0.y, r0.x, r0.x         */
12304         0x03000002, 0x80040000, 0x80550000, 0x80550000,                         /* add r0.z, r0.y, r0.y         */
12305         0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000,                         /* slt r0.y, c0.x, r0.w         */
12306         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
12307         0x03000002, 0x80040000, 0x81550000, 0xa0e40000,                         /* add r0.z, -r0.y, c0          */
12308         0x0300000c, 0x80080000, 0xa0000000, 0x80e40000,                         /* slt r0.w, c0.x, r0           */
12309         0x03000005, 0x80040000, 0x80ff0000, 0x80e40000,                         /* mul r0.z, r0.w, r0           */
12310         0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000,             /* mad r0.y, r0.z, c0, r0       */
12311         0x02000001, 0xe0030000, 0x80e40000,                                     /* mov oT0.xy, r0               */
12312         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
12313         0x0000ffff,                                                             /* end                          */
12314     };
12315
12316     static const struct
12317     {
12318         const char *name;
12319         const DWORD *ops;
12320         DWORD size;
12321         D3DCOLOR r600;
12322         D3DCOLOR nv40;
12323         D3DCOLOR nv50;
12324     }
12325     vs_body[] =
12326     {
12327         /* The basic ideas here are:
12328          *     2.0 * +/-INF == +/-INF
12329          *     NAN != NAN
12330          *
12331          * The vertex shader value is written to the red component, with 0.0
12332          * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
12333          * result in 0x00. The pixel shader value is written to the green
12334          * component, but here 0.0 also results in 0x00. The actual value is
12335          * written to the blue component.
12336          *
12337          * There are considerable differences between graphics cards in how
12338          * these are handled, but pow and nrm never generate INF or NAN. */
12339         {"log",     vs_log,     sizeof(vs_log),     0x00000000, 0x00ff0000, 0x00ff7f00},
12340         {"pow",     vs_pow,     sizeof(vs_pow),     0x000000ff, 0x0000ff00, 0x000000ff},
12341         {"nrm",     vs_nrm,     sizeof(vs_nrm),     0x00ff0000, 0x0000ff00, 0x00ff0000},
12342         {"rcp1",    vs_rcp1,    sizeof(vs_rcp1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12343         {"rcp2",    vs_rcp2,    sizeof(vs_rcp2),    0x00000000, 0x00ff0000, 0x00ff7f00},
12344         {"rsq1",    vs_rsq1,    sizeof(vs_rsq1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12345         {"rsq2",    vs_rsq2,    sizeof(vs_rsq2),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12346         {"lit",     vs_lit,     sizeof(vs_lit),     0x00ff0000, 0x00ff0000, 0x00ff0000},
12347     };
12348
12349     static const DWORD ps_code[] =
12350     {
12351         0xffff0200,                                                             /* ps_2_0                       */
12352         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
12353         0x0200001f, 0x80000000, 0xb0030000,                                     /* dcl t0.xy                    */
12354         0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000,                         /* max r1.x, t0, c0             */
12355         0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000,                         /* min r0.x, t0, c0             */
12356         0x03000002, 0x80010000, 0x80e40000, 0x81e40001,                         /* add r0.x, r0, -r1            */
12357         0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000,             /* mad r1.x, t0, c0.w. -t0      */
12358         0x02000023, 0x80010002, 0x80e40001,                                     /* abs r2.x, r1                 */
12359         0x02000023, 0x80010000, 0x80e40000,                                     /* abs r0.x, r0                 */
12360         0x02000023, 0x80010001, 0xb0e40000,                                     /* abs r1.x, t0                 */
12361         0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r2, c0.z, c0      */
12362         0x02000023, 0x80010002, 0x80e40002,                                     /* abs r2.x, r2                 */
12363         0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r1.x, -r1, c0.z, c0      */
12364         0x02000023, 0x80010001, 0x80e40001,                                     /* abs r1.x, r1                 */
12365         0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r3.x, -r2, c0.z, c0      */
12366         0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r1, c0.z, c0      */
12367         0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000,             /* cmp r0.x, -r0, c0.y, c0      */
12368         0x03000005, 0x80010002, 0x80e40002, 0x80e40003,                         /* mul r2.x, r2, r3             */
12369         0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000,             /* cmp r0.x, -r2, c0.z, r0      */
12370         0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000,             /* cmp r0.y, -r1.x, r0.x, c0.x  */
12371         0x02000001, 0x80050000, 0xb0c90000,                                     /* mov r0.xz, t0.yzxw           */
12372         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.w, c0.z               */
12373         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
12374         0x0000ffff,                                                             /* end                          */
12375     };
12376
12377     struct
12378     {
12379         float x, y, z;
12380         float s;
12381     }
12382     quad[] =
12383     {
12384         { -1.0f,  1.0f, 0.0f, 0.0f},
12385         {  1.0f,  1.0f, 1.0f, 0.0f},
12386         { -1.0f, -1.0f, 0.0f, 0.0f},
12387         {  1.0f, -1.0f, 1.0f, 0.0f},
12388     };
12389
12390     IDirect3DPixelShader9 *ps;
12391     UINT body_size = 0;
12392     DWORD *vs_code;
12393     D3DCAPS9 caps;
12394     HRESULT hr;
12395     UINT i;
12396
12397     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12398     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12399     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12400     {
12401         skip("No shader model 2.0 support, skipping floating point specials test.\n");
12402         return;
12403     }
12404
12405     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
12406     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12407
12408     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12409     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12410     hr = IDirect3DDevice9_SetPixelShader(device, ps);
12411     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12412
12413     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12414     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12415
12416     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
12417     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12418
12419     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12420     {
12421         if (vs_body[i].size > body_size) body_size = vs_body[i].size;
12422     }
12423
12424     vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
12425     memcpy(vs_code, vs_header, sizeof(vs_header));
12426
12427     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12428     {
12429         DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
12430         IDirect3DVertexShader9 *vs;
12431         D3DCOLOR color;
12432
12433         memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
12434         offset += vs_body[i].size / sizeof(*vs_body[i].ops);
12435         memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
12436
12437         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
12438         ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
12439         hr = IDirect3DDevice9_SetVertexShader(device, vs);
12440         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12441
12442         hr = IDirect3DDevice9_BeginScene(device);
12443         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12444         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12445         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12446         hr = IDirect3DDevice9_EndScene(device);
12447         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12448
12449         color = getPixelColor(device, 320, 240);
12450         ok(color_match(color, vs_body[i].r600, 1)
12451                 || color_match(color, vs_body[i].nv40, 1)
12452                 || color_match(color, vs_body[i].nv50, 1),
12453                 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
12454                 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
12455
12456         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12457         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12458
12459         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12460         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12461         IDirect3DVertexShader9_Release(vs);
12462     }
12463
12464     HeapFree(GetProcessHeap(), 0, vs_code);
12465
12466     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12467     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12468     IDirect3DPixelShader9_Release(ps);
12469 }
12470
12471 static void srgbwrite_format_test(IDirect3DDevice9 *device)
12472 {
12473     IDirect3D9 *d3d;
12474     IDirect3DSurface9 *rt, *backbuffer;
12475     IDirect3DTexture9 *texture;
12476     HRESULT hr;
12477     int i;
12478     DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
12479     static const struct
12480     {
12481         D3DFORMAT fmt;
12482         const char *name;
12483     }
12484     formats[] =
12485     {
12486         { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
12487         { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
12488         { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
12489         { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
12490         { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
12491     };
12492     static const struct
12493     {
12494         float x, y, z;
12495         float u, v;
12496     }
12497     quad[] =
12498     {
12499         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12500         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12501         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12502         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12503     };
12504
12505     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12506     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12507     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12508     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12509     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
12510     ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
12511     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12512     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12513     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12514     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12515
12516     for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
12517     {
12518         if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12519                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
12520         {
12521             skip("Format %s not supported as render target, skipping test.\n",
12522                     formats[i].name);
12523             continue;
12524         }
12525
12526         hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
12527                                             D3DPOOL_DEFAULT, &texture, NULL);
12528         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12529         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
12530         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12531
12532         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
12533         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12534         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12535         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12536         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
12537         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12538
12539         hr = IDirect3DDevice9_BeginScene(device);
12540         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12541         if(SUCCEEDED(hr))
12542         {
12543             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
12544             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12545             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
12546             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12547             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12548             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12549
12550             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
12551             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12552             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12553             ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12554             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
12555             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12556             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12557             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12558             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12559             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12560             hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12561             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12562
12563             hr = IDirect3DDevice9_EndScene(device);
12564             ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12565         }
12566
12567         IDirect3DSurface9_Release(rt);
12568         IDirect3DTexture9_Release(texture);
12569
12570         color = getPixelColor(device, 360, 240);
12571         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12572                                     D3DUSAGE_QUERY_SRGBWRITE,
12573                                     D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
12574         {
12575             /* Big slop for R5G6B5 */
12576             ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
12577                 formats[i].name, color_srgb, color);
12578         }
12579         else
12580         {
12581             /* Big slop for R5G6B5 */
12582             ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
12583                 formats[i].name, color_rgb, color);
12584         }
12585
12586         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12587         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12588     }
12589
12590     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12591     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12592
12593     IDirect3D9_Release(d3d);
12594     IDirect3DSurface9_Release(backbuffer);
12595 }
12596
12597 static void ds_size_test(IDirect3DDevice9 *device)
12598 {
12599     IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
12600     HRESULT hr;
12601     DWORD num_passes;
12602     struct
12603     {
12604         float x, y, z;
12605     }
12606     quad[] =
12607     {
12608         {-1.0,  -1.0,   0.0 },
12609         {-1.0,   1.0,   0.0 },
12610         { 1.0,  -1.0,   0.0 },
12611         { 1.0,   1.0,   0.0 }
12612     };
12613
12614     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12615     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12616     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
12617     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
12618     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
12619     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
12620
12621     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12622     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12623     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
12624     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12625     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12626     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12627     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12628     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12629     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12630     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12631     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
12632     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
12633     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12634     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12635     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12636     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12637     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12638     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12639
12640     /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
12641      * but does not change the surface's contents. */
12642     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
12643     ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
12644     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
12645     ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
12646     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
12647     ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12648
12649     /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
12650
12651     /* Turning on any depth-related state results in a ValidateDevice failure */
12652     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12653     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12654     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12655     ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12656         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12657     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12658     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12659     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12660     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12661     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12662     ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12663         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12664
12665     /* Try to draw with the device in an invalid state */
12666     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12667     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12668     hr = IDirect3DDevice9_BeginScene(device);
12669     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12670     if(SUCCEEDED(hr))
12671     {
12672         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12673         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12674         hr = IDirect3DDevice9_EndScene(device);
12675         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12676
12677         /* Don't check the resulting draw unless we find an app that needs it. On nvidia ValidateDevice
12678          * returns CONFLICTINGRENDERSTATE, so the result is undefined. On AMD d3d seems to assume the
12679          * stored Z buffer value is 0.0 for all pixels, even those that are covered by the depth buffer */
12680     }
12681
12682     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12683     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12684     hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12685     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12686     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12687     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12688
12689     IDirect3DSurface9_Release(readback);
12690     IDirect3DSurface9_Release(ds);
12691     IDirect3DSurface9_Release(rt);
12692     IDirect3DSurface9_Release(old_rt);
12693     IDirect3DSurface9_Release(old_ds);
12694 }
12695
12696 static void unbound_sampler_test(IDirect3DDevice9 *device)
12697 {
12698     HRESULT hr;
12699     IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
12700     IDirect3DSurface9 *rt, *old_rt;
12701     DWORD color;
12702
12703     static const DWORD ps_code[] =
12704     {
12705         0xffff0200,                                     /* ps_2_0           */
12706         0x0200001f, 0x90000000, 0xa00f0800,             /* dcl_2d s0        */
12707         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12708         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12709         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12710         0x0000ffff,                                     /* end              */
12711     };
12712     static const DWORD ps_code_cube[] =
12713     {
12714         0xffff0200,                                     /* ps_2_0           */
12715         0x0200001f, 0x98000000, 0xa00f0800,             /* dcl_cube s0      */
12716         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12717         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12718         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12719         0x0000ffff,                                     /* end              */
12720     };
12721     static const DWORD ps_code_volume[] =
12722     {
12723         0xffff0200,                                     /* ps_2_0           */
12724         0x0200001f, 0xa0000000, 0xa00f0800,             /* dcl_volume s0    */
12725         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12726         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12727         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12728         0x0000ffff,                                     /* end              */
12729     };
12730
12731     static const struct
12732     {
12733         float x, y, z;
12734         float u, v;
12735     }
12736     quad[] =
12737     {
12738         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12739         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12740         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12741         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12742     };
12743
12744     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12745     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
12746
12747     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12748     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12749     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
12750     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12751     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
12752     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12753
12754     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
12755     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12756
12757     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12758     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12759
12760     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12761     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12762
12763     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
12764     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12765
12766     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
12767     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
12768
12769     hr = IDirect3DDevice9_SetPixelShader(device, ps);
12770     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12771
12772     hr = IDirect3DDevice9_BeginScene(device);
12773     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12774     if(SUCCEEDED(hr))
12775     {
12776         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12777         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12778
12779         hr = IDirect3DDevice9_EndScene(device);
12780         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12781     }
12782
12783     color = getPixelColorFromSurface(rt, 32, 32);
12784     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12785
12786     /* Now try with a cube texture */
12787     hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
12788     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12789
12790     hr = IDirect3DDevice9_BeginScene(device);
12791     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12792     if (SUCCEEDED(hr))
12793     {
12794         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12795         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12796
12797         hr = IDirect3DDevice9_EndScene(device);
12798         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12799     }
12800
12801     color = getPixelColorFromSurface(rt, 32, 32);
12802     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12803
12804     /* And then with a volume texture */
12805     hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
12806     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12807
12808     hr = IDirect3DDevice9_BeginScene(device);
12809     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12810     if (SUCCEEDED(hr))
12811     {
12812         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12813         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12814
12815         hr = IDirect3DDevice9_EndScene(device);
12816         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12817     }
12818
12819     color = getPixelColorFromSurface(rt, 32, 32);
12820     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12821
12822     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12823     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12824
12825     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12826     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12827
12828     IDirect3DSurface9_Release(rt);
12829     IDirect3DSurface9_Release(old_rt);
12830     IDirect3DPixelShader9_Release(ps);
12831     IDirect3DPixelShader9_Release(ps_cube);
12832     IDirect3DPixelShader9_Release(ps_volume);
12833 }
12834
12835 static void update_surface_test(IDirect3DDevice9 *device)
12836 {
12837     static const BYTE blocks[][8] =
12838     {
12839         {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
12840         {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
12841         {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
12842         {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
12843         {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
12844         {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
12845         {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
12846     };
12847     static const struct
12848     {
12849         UINT x, y;
12850         D3DCOLOR color;
12851     }
12852     expected_colors[] =
12853     {
12854         { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
12855         { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
12856         {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
12857         {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12858         {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12859         {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12860         {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
12861     };
12862     static const struct
12863     {
12864         float x, y, z, w;
12865         float u, v;
12866     }
12867     tri[] =
12868     {
12869         {  0.0f, 480.0f, 0.0f,  1.0f,   0.0f, 0.0f},
12870         {  0.0f,   0.0f, 0.0f,  1.0f,   0.0f, 1.0f},
12871         {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
12872     };
12873     static const RECT rect_2x2 = {0, 0, 2, 2};
12874     static const struct
12875     {
12876         UINT src_level;
12877         UINT dst_level;
12878         const RECT *r;
12879         HRESULT hr;
12880     }
12881     block_size_tests[] =
12882     {
12883         {1, 0, NULL,      D3D_OK},
12884         {0, 1, NULL,      D3DERR_INVALIDCALL},
12885         {5, 4, NULL,      D3DERR_INVALIDCALL},
12886         {4, 5, NULL,      D3DERR_INVALIDCALL},
12887         {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
12888         {5, 5, &rect_2x2, D3D_OK},
12889     };
12890
12891     IDirect3DSurface9 *src_surface, *dst_surface;
12892     IDirect3DTexture9 *src_tex, *dst_tex;
12893     IDirect3D9 *d3d;
12894     UINT count, i;
12895     HRESULT hr;
12896
12897     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12898     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12899
12900     hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12901             D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
12902     IDirect3D9_Release(d3d);
12903     if (FAILED(hr))
12904     {
12905         skip("DXT1 not supported, skipping test.\n");
12906         return;
12907     }
12908
12909     IDirect3D9_Release(d3d);
12910
12911     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
12912     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12913     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
12914     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12915
12916     count = IDirect3DTexture9_GetLevelCount(src_tex);
12917     ok(count == 7, "Got level count %u, expected 7.\n", count);
12918
12919     for (i = 0; i < count; ++i)
12920     {
12921         UINT row_count, block_count, x, y;
12922         D3DSURFACE_DESC desc;
12923         BYTE *row, *block;
12924         D3DLOCKED_RECT r;
12925
12926         hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
12927         ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
12928
12929         hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
12930         ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
12931
12932         row_count = ((desc.Height + 3) & ~3) / 4;
12933         block_count = ((desc.Width + 3) & ~3) / 4;
12934         row = r.pBits;
12935
12936         for (y = 0; y < row_count; ++y)
12937         {
12938             block = row;
12939             for (x = 0; x < block_count; ++x)
12940             {
12941                 memcpy(block, blocks[i], sizeof(blocks[i]));
12942                 block += sizeof(blocks[i]);
12943             }
12944             row += r.Pitch;
12945         }
12946
12947         hr = IDirect3DTexture9_UnlockRect(src_tex, i);
12948         ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
12949     }
12950
12951     for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
12952     {
12953         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
12954         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12955         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
12956         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12957
12958         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
12959         ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
12960                 hr, i, block_size_tests[i].hr);
12961
12962         IDirect3DSurface9_Release(dst_surface);
12963         IDirect3DSurface9_Release(src_surface);
12964     }
12965
12966     for (i = 0; i < count; ++i)
12967     {
12968         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
12969         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12970         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
12971         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12972
12973         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
12974         ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
12975
12976         IDirect3DSurface9_Release(dst_surface);
12977         IDirect3DSurface9_Release(src_surface);
12978     }
12979
12980     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12981     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12982     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12983     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12984     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
12985     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12986     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
12987     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12988     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12989     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12990     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12991     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12992
12993     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
12994     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12995
12996     hr = IDirect3DDevice9_BeginScene(device);
12997     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12998     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
12999     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13000     hr = IDirect3DDevice9_EndScene(device);
13001     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13002
13003     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13004     {
13005         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13006         ok(color_match(color, expected_colors[i].color, 0),
13007                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13008                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13009     }
13010
13011     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13012     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13013
13014     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13015     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13016     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
13017     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
13018     IDirect3DTexture9_Release(dst_tex);
13019     IDirect3DTexture9_Release(src_tex);
13020 }
13021
13022 static void multisample_get_rtdata_test(IDirect3DDevice9 *device)
13023 {
13024     IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
13025     IDirect3D9 *d3d9;
13026     HRESULT hr;
13027
13028     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
13029     ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
13030     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13031             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13032     IDirect3D9_Release(d3d9);
13033     if (FAILED(hr))
13034     {
13035         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
13036         return;
13037     }
13038
13039     hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
13040             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13041     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13042     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
13043             D3DPOOL_SYSTEMMEM, &readback, NULL);
13044     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13045
13046     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13047     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13048     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13049     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13050
13051     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13052     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13053     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13054     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13055
13056     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
13057     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13058     hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
13059     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
13060
13061     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13062     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13063     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13064     ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13065
13066     IDirect3DSurface9_Release(original_ds);
13067     IDirect3DSurface9_Release(original_rt);
13068     IDirect3DSurface9_Release(readback);
13069     IDirect3DSurface9_Release(rt);
13070 }
13071
13072 static void multisampled_depth_buffer_test(IDirect3D9 *d3d9)
13073 {
13074     IDirect3DDevice9 *device = 0;
13075     IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
13076     D3DCAPS9 caps;
13077     HRESULT hr;
13078     D3DPRESENT_PARAMETERS present_parameters;
13079     unsigned int i;
13080     static const struct
13081     {
13082         float x, y, z;
13083         D3DCOLOR color;
13084     }
13085     quad_1[] =
13086     {
13087         { -1.0f,  1.0f, 0.0f, 0xffff0000},
13088         {  1.0f,  1.0f, 1.0f, 0xffff0000},
13089         { -1.0f, -1.0f, 0.0f, 0xffff0000},
13090         {  1.0f, -1.0f, 1.0f, 0xffff0000},
13091     },
13092     quad_2[] =
13093     {
13094         { -1.0f,  1.0f, 1.0f, 0xff0000ff},
13095         {  1.0f,  1.0f, 0.0f, 0xff0000ff},
13096         { -1.0f, -1.0f, 1.0f, 0xff0000ff},
13097         {  1.0f, -1.0f, 0.0f, 0xff0000ff},
13098     };
13099     static const struct
13100     {
13101         UINT x, y;
13102         D3DCOLOR color;
13103     }
13104     expected_colors[] =
13105     {
13106         { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13107         {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13108         {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13109         {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13110         { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13111         {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13112         {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13113         {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13114     };
13115
13116     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13117             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13118     if (FAILED(hr))
13119     {
13120         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
13121         return;
13122     }
13123     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13124             D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13125     if (FAILED(hr))
13126     {
13127         skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
13128         return;
13129     }
13130
13131     ZeroMemory(&present_parameters, sizeof(present_parameters));
13132     present_parameters.Windowed = TRUE;
13133     present_parameters.hDeviceWindow = create_window();
13134     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13135     present_parameters.BackBufferWidth = 640;
13136     present_parameters.BackBufferHeight = 480;
13137     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13138     present_parameters.EnableAutoDepthStencil = TRUE;
13139     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13140     present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13141
13142     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13143             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13144             &present_parameters, &device);
13145     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13146
13147     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13148     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13149     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13150     {
13151         skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
13152         goto cleanup;
13153     }
13154
13155     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13156             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13157     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13158     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13159             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13160     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13161
13162     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13163     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13164     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13165     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13166
13167     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13168     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13169     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13170     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13171     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13172     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13173     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13174     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13175     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13176     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13177
13178     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13179     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13180
13181     /* Render onscreen and then offscreen */
13182     hr = IDirect3DDevice9_BeginScene(device);
13183     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13184     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13185     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13186     hr = IDirect3DDevice9_EndScene(device);
13187     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13188
13189     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
13190     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13191     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13192     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13193
13194     hr = IDirect3DDevice9_BeginScene(device);
13195     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13196     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13197     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13198     hr = IDirect3DDevice9_EndScene(device);
13199     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13200
13201     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
13202     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13203
13204     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13205     {
13206         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13207         ok(color_match(color, expected_colors[i].color, 1),
13208                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13209                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13210     }
13211
13212     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13213     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13214     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13215     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13216
13217     /* Render offscreen and then onscreen */
13218     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13219     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13220     IDirect3DSurface9_Release(ds);
13221     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13222             D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13223     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13224     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13225
13226     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13227     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13228
13229     hr = IDirect3DDevice9_BeginScene(device);
13230     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13231     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13232     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13233     hr = IDirect3DDevice9_EndScene(device);
13234     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13235
13236     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13237     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13238     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13239     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13240
13241     hr = IDirect3DDevice9_BeginScene(device);
13242     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13243     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13244     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13245     hr = IDirect3DDevice9_EndScene(device);
13246     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13247
13248     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13249     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13250
13251     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13252     {
13253         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13254         ok(color_match(color, expected_colors[i].color, 1),
13255                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13256                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13257     }
13258
13259     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13260     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13261
13262     IDirect3DSurface9_Release(ds);
13263     IDirect3DSurface9_Release(readback);
13264     IDirect3DSurface9_Release(rt);
13265     IDirect3DSurface9_Release(original_rt);
13266     cleanup_device(device);
13267
13268     ZeroMemory(&present_parameters, sizeof(present_parameters));
13269     present_parameters.Windowed = TRUE;
13270     present_parameters.hDeviceWindow = create_window();
13271     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13272     present_parameters.BackBufferWidth = 640;
13273     present_parameters.BackBufferHeight = 480;
13274     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13275     present_parameters.EnableAutoDepthStencil = TRUE;
13276     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13277     present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13278
13279     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13280             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13281             &present_parameters, &device);
13282     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13283
13284     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
13285     ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
13286
13287     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13288             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13289     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13290     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13291             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13292     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13293     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13294             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
13295     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13296
13297     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13298     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13299     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13300     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13301     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13302     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13303     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13304     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13305
13306     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13307     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13308     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13309     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13310     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13311     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13312     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13313     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13314     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13315     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13316
13317     /* Render to a multisampled offscreen frame buffer and then blit to
13318      * the onscreen (not multisampled) frame buffer. */
13319     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13320     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13321
13322     hr = IDirect3DDevice9_BeginScene(device);
13323     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13324     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13325     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13326     hr = IDirect3DDevice9_EndScene(device);
13327     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13328
13329     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13330     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13331     hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
13332     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13333
13334     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13335     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13336     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13337     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13338
13339     hr = IDirect3DDevice9_BeginScene(device);
13340     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13341     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13342     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13343     hr = IDirect3DDevice9_EndScene(device);
13344     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13345
13346     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13347     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13348
13349     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13350     {
13351         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13352         if (i % 4 < 2)
13353             todo_wine ok(color_match(color, expected_colors[i].color, 1),
13354                     "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13355                     expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13356         else
13357             ok(color_match(color, expected_colors[i].color, 1),
13358                     "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13359                     expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13360     }
13361
13362     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13363     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13364
13365     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13366     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13367     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13368     ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13369
13370     IDirect3DSurface9_Release(original_ds);
13371     IDirect3DSurface9_Release(original_rt);
13372     IDirect3DSurface9_Release(ds);
13373     IDirect3DSurface9_Release(readback);
13374     IDirect3DSurface9_Release(rt);
13375 cleanup:
13376     cleanup_device(device);
13377 }
13378
13379 static void resz_test(IDirect3D9 *d3d9)
13380 {
13381     IDirect3DDevice9 *device = 0;
13382     IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
13383     D3DCAPS9 caps;
13384     HRESULT hr;
13385     D3DPRESENT_PARAMETERS present_parameters;
13386     unsigned int i;
13387     static const DWORD ps_code[] =
13388     {
13389         0xffff0200,                                                             /* ps_2_0                       */
13390         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
13391         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
13392         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
13393         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
13394         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
13395         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
13396         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
13397         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
13398         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
13399         0x0000ffff,                                                             /* end                          */
13400     };
13401     struct
13402     {
13403         float x, y, z;
13404         float s, t, p, q;
13405     }
13406     quad[] =
13407     {
13408         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13409         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13410         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13411         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13412     };
13413     struct
13414     {
13415         UINT x, y;
13416         D3DCOLOR color;
13417     }
13418     expected_colors[] =
13419     {
13420         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13421         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13422         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13423         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13424         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13425         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13426         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13427         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13428     };
13429     IDirect3DTexture9 *texture;
13430     IDirect3DPixelShader9 *ps;
13431     DWORD value;
13432
13433     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13434             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13435     if (FAILED(hr))
13436     {
13437         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
13438         return;
13439     }
13440     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13441             D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13442     if (FAILED(hr))
13443     {
13444         skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
13445         return;
13446     }
13447
13448     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13449             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
13450     if (FAILED(hr))
13451     {
13452         skip("No INTZ support, skipping RESZ test.\n");
13453         return;
13454     }
13455
13456     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13457             D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'));
13458     if (FAILED(hr))
13459     {
13460         skip("No RESZ support, skipping RESZ test.\n");
13461         return;
13462     }
13463
13464     ZeroMemory(&present_parameters, sizeof(present_parameters));
13465     present_parameters.Windowed = TRUE;
13466     present_parameters.hDeviceWindow = create_window();
13467     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13468     present_parameters.BackBufferWidth = 640;
13469     present_parameters.BackBufferHeight = 480;
13470     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13471     present_parameters.EnableAutoDepthStencil = FALSE;
13472     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13473     present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13474
13475     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13476             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13477     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13478
13479     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13480     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13481     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
13482     {
13483         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
13484         cleanup_device(device);
13485         return;
13486     }
13487     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13488     {
13489         skip("No unconditional NP2 texture support, skipping INTZ test.\n");
13490         cleanup_device(device);
13491         return;
13492     }
13493
13494     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13495     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13496
13497     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13498             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13499     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13500     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13501             D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13502     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13503             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13504     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13505
13506     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13507             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13508     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13509     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13510     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13511     hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13512     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13513     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13514     ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13515     IDirect3DSurface9_Release(intz_ds);
13516     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13517     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13518
13519     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13520     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13521     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13522     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13523     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13524     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13525     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13526     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13527     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13528     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13529
13530     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13531     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13532     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13533     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13534     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13535     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13536     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13537     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13538     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13539     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13540
13541     /* Render offscreen (multisampled), blit the depth buffer
13542      * into the INTZ texture and then check its contents */
13543     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13544     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13545     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13546     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13547     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13548     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13549
13550     hr = IDirect3DDevice9_BeginScene(device);
13551     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13552     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13553     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13554
13555     /* The destination depth texture has to be bound to sampler 0 */
13556     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13557     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13558
13559     /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
13560     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13561     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13562     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13563     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13564     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13565     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13566     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13567     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13568     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13569     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13570     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13571     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13572     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13573     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13574
13575     /* The actual multisampled depth buffer resolve happens here */
13576     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13577     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13578     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13579     ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13580
13581     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13582     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13583     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13584     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13585
13586     /* Read the depth values back */
13587     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13588     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13589     hr = IDirect3DDevice9_EndScene(device);
13590     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13591
13592     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13593     {
13594         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13595         ok(color_match(color, expected_colors[i].color, 1),
13596                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13597                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13598     }
13599
13600     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13601     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13602
13603     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13604     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13605     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13606     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13607     IDirect3DSurface9_Release(ds);
13608     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13609     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13610     IDirect3DTexture9_Release(texture);
13611     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13612     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13613     IDirect3DPixelShader9_Release(ps);
13614     IDirect3DSurface9_Release(readback);
13615     IDirect3DSurface9_Release(original_rt);
13616     IDirect3DSurface9_Release(rt);
13617     cleanup_device(device);
13618
13619
13620     ZeroMemory(&present_parameters, sizeof(present_parameters));
13621     present_parameters.Windowed = TRUE;
13622     present_parameters.hDeviceWindow = create_window();
13623     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13624     present_parameters.BackBufferWidth = 640;
13625     present_parameters.BackBufferHeight = 480;
13626     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13627     present_parameters.EnableAutoDepthStencil = TRUE;
13628     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13629     present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13630
13631     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13632             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13633     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13634
13635     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13636     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13637     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13638     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13639     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13640             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13641     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13642     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13643             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13644     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13645     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13646     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13647     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13648     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13649     hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13650     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13651     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13652     ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13653     IDirect3DSurface9_Release(intz_ds);
13654     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13655     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13656
13657     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13658     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13659     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13660     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13661     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13662     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13663     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13664     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13665     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13666     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13667
13668     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13669     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13670     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13671     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13672     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13673     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13674     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13675     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13676     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13677     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13678
13679     /* Render onscreen, blit the depth buffer into the INTZ texture
13680      * and then check its contents */
13681     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13682     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13683     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13684     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13685     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13686     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13687
13688     hr = IDirect3DDevice9_BeginScene(device);
13689     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13690     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13691     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13692     hr = IDirect3DDevice9_EndScene(device);
13693     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13694
13695     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13696     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13697
13698     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13699     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13700     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13701     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13702     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13703     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13704     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13705     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13706     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13707     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13708     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13709     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13710     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13711     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13712
13713     /* The actual multisampled depth buffer resolve happens here */
13714     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13715     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13716     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13717     ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13718
13719     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13720     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13721     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13722     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13723
13724     /* Read the depth values back */
13725     hr = IDirect3DDevice9_BeginScene(device);
13726     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13727     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13728     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13729     hr = IDirect3DDevice9_EndScene(device);
13730     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13731
13732     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13733     {
13734         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13735         ok(color_match(color, expected_colors[i].color, 1),
13736                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13737                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13738     }
13739
13740     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13741     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13742
13743
13744     /* Test edge cases - try with no texture at all */
13745     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13746     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13747     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13748     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13749
13750     hr = IDirect3DDevice9_BeginScene(device);
13751     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13752     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13753     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13754     hr = IDirect3DDevice9_EndScene(device);
13755     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13756
13757     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13758     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13759
13760     /* With a non-multisampled depth buffer */
13761     IDirect3DSurface9_Release(ds);
13762     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13763             D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
13764
13765     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13766     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13767     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13768     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13769     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13770     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13771
13772     hr = IDirect3DDevice9_BeginScene(device);
13773     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13774     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13775     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13776
13777     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13778     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13779
13780     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13781     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13782     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13783     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13784     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13785     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13786     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13787     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13788     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13789     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13790     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13791     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13792     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13793     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13794     hr = IDirect3DDevice9_EndScene(device);
13795     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13796
13797     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13798     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13799
13800     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13801     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13802
13803     /* Read the depth values back. */
13804     hr = IDirect3DDevice9_BeginScene(device);
13805     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13806     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13807     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13808     hr = IDirect3DDevice9_EndScene(device);
13809     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13810
13811     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13812     {
13813         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13814         ok(color_match(color, expected_colors[i].color, 1),
13815                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13816                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13817     }
13818
13819     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13820     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13821
13822     /* Without a current depth-stencil buffer set */
13823     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13824     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13825     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13826     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13827
13828     hr = IDirect3DDevice9_BeginScene(device);
13829     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13830     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13831     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13832     hr = IDirect3DDevice9_EndScene(device);
13833     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13834
13835     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13836     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13837
13838     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13839     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13840     IDirect3DSurface9_Release(ds);
13841     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13842     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13843     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13844     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13845     IDirect3DTexture9_Release(texture);
13846     IDirect3DPixelShader9_Release(ps);
13847     IDirect3DSurface9_Release(readback);
13848     IDirect3DSurface9_Release(original_rt);
13849     cleanup_device(device);
13850 }
13851
13852 static void zenable_test(IDirect3DDevice9 *device)
13853 {
13854     static const struct
13855     {
13856         struct vec4 position;
13857         D3DCOLOR diffuse;
13858     }
13859     tquad[] =
13860     {
13861         {{  0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
13862         {{  0.0f,   0.0f, -0.5f, 1.0f}, 0xff00ff00},
13863         {{640.0f, 480.0f,  1.5f, 1.0f}, 0xff00ff00},
13864         {{640.0f,   0.0f,  1.5f, 1.0f}, 0xff00ff00},
13865     };
13866     D3DCOLOR color;
13867     D3DCAPS9 caps;
13868     HRESULT hr;
13869     UINT x, y;
13870     UINT i, j;
13871
13872     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
13873     ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
13874     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13875     ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
13876
13877     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
13878     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13879     hr = IDirect3DDevice9_BeginScene(device);
13880     ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13881     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
13882     ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13883     hr = IDirect3DDevice9_EndScene(device);
13884     ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13885
13886     for (i = 0; i < 4; ++i)
13887     {
13888         for (j = 0; j < 4; ++j)
13889         {
13890             x = 80 * ((2 * j) + 1);
13891             y = 60 * ((2 * i) + 1);
13892             color = getPixelColor(device, x, y);
13893             ok(color_match(color, 0x0000ff00, 1),
13894                     "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
13895         }
13896     }
13897
13898     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13899     ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
13900
13901     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13902     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13903
13904     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
13905             && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
13906     {
13907         static const DWORD vs_code[] =
13908         {
13909             0xfffe0101,                                 /* vs_1_1           */
13910             0x0000001f, 0x80000000, 0x900f0000,         /* dcl_position v0  */
13911             0x00000001, 0xc00f0000, 0x90e40000,         /* mov oPos, v0     */
13912             0x00000001, 0xd00f0000, 0x90e40000,         /* mov oD0, v0      */
13913             0x0000ffff
13914         };
13915         static const DWORD ps_code[] =
13916         {
13917             0xffff0101,                                 /* ps_1_1           */
13918             0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
13919             0x0000ffff                                  /* end              */
13920         };
13921         static const struct vec3 quad[] =
13922         {
13923             {-1.0f, -1.0f, -0.5f},
13924             {-1.0f,  1.0f, -0.5f},
13925             { 1.0f, -1.0f,  1.5f},
13926             { 1.0f,  1.0f,  1.5f},
13927         };
13928         static const D3DCOLOR expected[] =
13929         {
13930             0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
13931             0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
13932             0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
13933             0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
13934         };
13935
13936         IDirect3DVertexShader9 *vs;
13937         IDirect3DPixelShader9 *ps;
13938
13939         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13940         ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
13941         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
13942         ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
13943         hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13944         ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
13945         hr = IDirect3DDevice9_SetVertexShader(device, vs);
13946         ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13947         hr = IDirect3DDevice9_SetPixelShader(device, ps);
13948         ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
13949
13950         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
13951         ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13952         hr = IDirect3DDevice9_BeginScene(device);
13953         ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13954         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13955         ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13956         hr = IDirect3DDevice9_EndScene(device);
13957         ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13958
13959         for (i = 0; i < 4; ++i)
13960         {
13961             for (j = 0; j < 4; ++j)
13962             {
13963                 x = 80 * ((2 * j) + 1);
13964                 y = 60 * ((2 * i) + 1);
13965                 color = getPixelColor(device, x, y);
13966                 ok(color_match(color, expected[i * 4 + j], 1),
13967                         "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
13968             }
13969         }
13970
13971         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13972         ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
13973
13974         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13975         ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
13976         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
13977         ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13978         IDirect3DPixelShader9_Release(ps);
13979         IDirect3DVertexShader9_Release(vs);
13980     }
13981 }
13982
13983 START_TEST(visual)
13984 {
13985     IDirect3D9 *d3d9;
13986     IDirect3DDevice9 *device_ptr;
13987     D3DCAPS9 caps;
13988     HRESULT hr;
13989     DWORD color;
13990
13991     d3d9_handle = LoadLibraryA("d3d9.dll");
13992     if (!d3d9_handle)
13993     {
13994         skip("Could not load d3d9.dll\n");
13995         return;
13996     }
13997
13998     device_ptr = init_d3d9();
13999     if (!device_ptr)
14000     {
14001         skip("Creating the device failed\n");
14002         return;
14003     }
14004
14005     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
14006
14007     /* Check for the reliability of the returned data */
14008     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
14009     if(FAILED(hr))
14010     {
14011         skip("Clear failed, can't assure correctness of the test results, skipping\n");
14012         goto cleanup;
14013     }
14014
14015     color = getPixelColor(device_ptr, 1, 1);
14016     if(color !=0x00ff0000)
14017     {
14018         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
14019         goto cleanup;
14020     }
14021     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
14022
14023     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
14024     if(FAILED(hr))
14025     {
14026         skip("Clear failed, can't assure correctness of the test results, skipping\n");
14027         goto cleanup;
14028     }
14029
14030     color = getPixelColor(device_ptr, 639, 479);
14031     if(color != 0x0000ddee)
14032     {
14033         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
14034         goto cleanup;
14035     }
14036     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
14037
14038     /* Now execute the real tests */
14039     depth_clamp_test(device_ptr);
14040     stretchrect_test(device_ptr);
14041     lighting_test(device_ptr);
14042     clear_test(device_ptr);
14043     color_fill_test(device_ptr);
14044     fog_test(device_ptr);
14045     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
14046     {
14047         test_cube_wrap(device_ptr);
14048     } else {
14049         skip("No cube texture support\n");
14050     }
14051     z_range_test(device_ptr);
14052     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
14053     {
14054         maxmip_test(device_ptr);
14055     }
14056     else
14057     {
14058         skip("No mipmap support\n");
14059     }
14060     offscreen_test(device_ptr);
14061     ds_size_test(device_ptr);
14062     alpha_test(device_ptr);
14063     shademode_test(device_ptr);
14064     srgbtexture_test(device_ptr);
14065     release_buffer_test(device_ptr);
14066     float_texture_test(device_ptr);
14067     g16r16_texture_test(device_ptr);
14068     pixelshader_blending_test(device_ptr);
14069     texture_transform_flags_test(device_ptr);
14070     autogen_mipmap_test(device_ptr);
14071     fixed_function_decl_test(device_ptr);
14072     conditional_np2_repeat_test(device_ptr);
14073     fixed_function_bumpmap_test(device_ptr);
14074     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
14075         stencil_cull_test(device_ptr);
14076     } else {
14077         skip("No two sided stencil support\n");
14078     }
14079     pointsize_test(device_ptr);
14080     tssargtemp_test(device_ptr);
14081     np2_stretch_rect_test(device_ptr);
14082     yuv_color_test(device_ptr);
14083     zwriteenable_test(device_ptr);
14084     alphatest_test(device_ptr);
14085     viewport_test(device_ptr);
14086
14087     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
14088     {
14089         test_constant_clamp_vs(device_ptr);
14090         test_compare_instructions(device_ptr);
14091     }
14092     else skip("No vs_1_1 support\n");
14093
14094     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
14095     {
14096         test_mova(device_ptr);
14097         loop_index_test(device_ptr);
14098         sincos_test(device_ptr);
14099         sgn_test(device_ptr);
14100         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14101             test_vshader_input(device_ptr);
14102             test_vshader_float16(device_ptr);
14103             stream_test(device_ptr);
14104         } else {
14105             skip("No vs_3_0 support\n");
14106         }
14107     }
14108     else skip("No vs_2_0 support\n");
14109
14110     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0) && caps.PixelShaderVersion >= D3DPS_VERSION(2, 0))
14111     {
14112         fog_with_shader_test(device_ptr);
14113     }
14114     else skip("No vs_2_0 and ps_2_0 support\n");
14115
14116     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
14117     {
14118         texbem_test(device_ptr);
14119         texdepth_test(device_ptr);
14120         texkill_test(device_ptr);
14121         x8l8v8u8_test(device_ptr);
14122         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
14123             constant_clamp_ps_test(device_ptr);
14124             cnd_test(device_ptr);
14125             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
14126                 dp2add_ps_test(device_ptr);
14127                 unbound_sampler_test(device_ptr);
14128                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14129                     nested_loop_test(device_ptr);
14130                     pretransformed_varying_test(device_ptr);
14131                     vFace_register_test(device_ptr);
14132                     vpos_register_test(device_ptr);
14133                     multiple_rendertargets_test(device_ptr);
14134                 } else {
14135                     skip("No ps_3_0 or vs_3_0 support\n");
14136                 }
14137             } else {
14138                 skip("No ps_2_0 support\n");
14139             }
14140         }
14141     }
14142     else skip("No ps_1_1 support\n");
14143
14144     texop_test(device_ptr);
14145     texop_range_test(device_ptr);
14146     alphareplicate_test(device_ptr);
14147     dp3_alpha_test(device_ptr);
14148     depth_buffer_test(device_ptr);
14149     depth_buffer2_test(device_ptr);
14150     depth_blit_test(device_ptr);
14151     intz_test(device_ptr);
14152     shadow_test(device_ptr);
14153     fp_special_test(device_ptr);
14154     depth_bounds_test(device_ptr);
14155     srgbwrite_format_test(device_ptr);
14156     clip_planes_test(device_ptr);
14157     update_surface_test(device_ptr);
14158     multisample_get_rtdata_test(device_ptr);
14159     zenable_test(device_ptr);
14160
14161     hr = IDirect3DDevice9_GetDirect3D(device_ptr, &d3d9);
14162     ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
14163     cleanup_device(device_ptr);
14164     device_ptr = NULL;
14165
14166     multisampled_depth_buffer_test(d3d9);
14167     resz_test(d3d9);
14168
14169     IDirect3D9_Release(d3d9);
14170
14171 cleanup:
14172     cleanup_device(device_ptr);
14173 }