d3drm: Implement IDirect3DRMMesh_GetGroup.
[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     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8618     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8619     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8620     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8621     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8622     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8623     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8624     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8625     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8626     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8627     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8628     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8629
8630     /* 2nd pass: Make the stencil values visible */
8631     hr = IDirect3DDevice9_BeginScene(device);
8632     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8633     if(SUCCEEDED(hr))
8634     {
8635         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8636         ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8637         for (i = 0; i < 16; ++i)
8638         {
8639             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8640             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8641
8642             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8643             painter[1].diffuse = (i * 16);
8644             painter[2].diffuse = (i * 16);
8645             painter[3].diffuse = (i * 16);
8646             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8647             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8648         }
8649         hr = IDirect3DDevice9_EndScene(device);
8650         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8651     }
8652
8653     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8654     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8655
8656     color = getPixelColor(device, 160, 420);
8657     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8658     color = getPixelColor(device, 160, 300);
8659     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8660
8661     color = getPixelColor(device, 480, 420);
8662     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8663     color = getPixelColor(device, 480, 300);
8664     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8665
8666     color = getPixelColor(device, 160, 180);
8667     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8668     color = getPixelColor(device, 160, 60);
8669     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8670
8671     color = getPixelColor(device, 480, 180);
8672     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8673     color = getPixelColor(device, 480, 60);
8674     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8675
8676     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8677     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8678 }
8679
8680 static void vpos_register_test(IDirect3DDevice9 *device)
8681 {
8682     HRESULT hr;
8683     DWORD color;
8684     const DWORD shader_code[] = {
8685     0xffff0300,                                                             /* ps_3_0                     */
8686     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8687     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8688     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8689     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8690     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8691     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8692     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8693     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8694     0x0000ffff                                                              /* end                        */
8695     };
8696     const DWORD shader_frac_code[] = {
8697     0xffff0300,                                                             /* ps_3_0                     */
8698     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8699     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8700     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8701     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8702     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8703     0x0000ffff                                                              /* end                        */
8704     };
8705     const DWORD vshader_code[] = {
8706         0xfffe0300,                                                             /* vs_3_0               */
8707         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8708         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8709         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8710         0x0000ffff                                                              /* end                  */
8711     };
8712     IDirect3DVertexShader9 *vshader;
8713     IDirect3DPixelShader9 *shader, *shader_frac;
8714     IDirect3DSurface9 *surface = NULL, *backbuffer;
8715     const float quad[] = {
8716         -1.0,   -1.0,   0.1,    0.0,    0.0,
8717          1.0,   -1.0,   0.1,    1.0,    0.0,
8718         -1.0,    1.0,   0.1,    0.0,    1.0,
8719          1.0,    1.0,   0.1,    1.0,    1.0,
8720     };
8721     D3DLOCKED_RECT lr;
8722     float constant[4] = {1.0, 0.0, 320, 240};
8723     DWORD *pos;
8724
8725     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8726     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8727     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8728     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8729     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8730     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8731     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8732     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8733     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8734     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8735     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8736     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8737     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8738     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8739     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8740     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8741
8742     hr = IDirect3DDevice9_BeginScene(device);
8743     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8744     if(SUCCEEDED(hr)) {
8745         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8746         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8747         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8748         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8749         hr = IDirect3DDevice9_EndScene(device);
8750         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8751     }
8752
8753     /* This has to be pixel exact */
8754     color = getPixelColor(device, 319, 239);
8755     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8756     color = getPixelColor(device, 320, 239);
8757     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8758     color = getPixelColor(device, 319, 240);
8759     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8760     color = getPixelColor(device, 320, 240);
8761     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8762     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8763
8764     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8765                                              &surface, NULL);
8766     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8767     hr = IDirect3DDevice9_BeginScene(device);
8768     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8769     if(SUCCEEDED(hr)) {
8770         constant[2] = 16; constant[3] = 16;
8771         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8772         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8773         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8774         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8775         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8776         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8777         hr = IDirect3DDevice9_EndScene(device);
8778         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8779     }
8780     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8781     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8782
8783     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8784     color = *pos & 0x00ffffff;
8785     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8786     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8787     color = *pos & 0x00ffffff;
8788     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8789     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8790     color = *pos & 0x00ffffff;
8791     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8792     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8793     color = *pos & 0x00ffffff;
8794     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8795
8796     hr = IDirect3DSurface9_UnlockRect(surface);
8797     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8798
8799     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8800      * have full control over the multisampling setting inside this test
8801      */
8802     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8803     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8804     hr = IDirect3DDevice9_BeginScene(device);
8805     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8806     if(SUCCEEDED(hr)) {
8807         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8808         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8809         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8810         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8811         hr = IDirect3DDevice9_EndScene(device);
8812         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8813     }
8814     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8815     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8816
8817     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8818     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8819
8820     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8821     color = *pos & 0x00ffffff;
8822     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8823
8824     hr = IDirect3DSurface9_UnlockRect(surface);
8825     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8826
8827     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8828     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8829     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8830     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8831     IDirect3DPixelShader9_Release(shader);
8832     IDirect3DPixelShader9_Release(shader_frac);
8833     IDirect3DVertexShader9_Release(vshader);
8834     if(surface) IDirect3DSurface9_Release(surface);
8835     IDirect3DSurface9_Release(backbuffer);
8836 }
8837
8838 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8839 {
8840     D3DCOLOR color;
8841
8842     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8843     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8844     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8845     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8846     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8847
8848     ++r;
8849     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8850     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8851     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8852     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8853     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8854
8855     return TRUE;
8856 }
8857
8858 static void pointsize_test(IDirect3DDevice9 *device)
8859 {
8860     HRESULT hr;
8861     D3DCAPS9 caps;
8862     D3DMATRIX matrix;
8863     D3DMATRIX identity;
8864     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8865     DWORD color;
8866     IDirect3DSurface9 *rt, *backbuffer;
8867     IDirect3DTexture9 *tex1, *tex2;
8868     RECT rect = {0, 0, 128, 128};
8869     D3DLOCKED_RECT lr;
8870     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8871                                 0x00000000, 0x00000000};
8872     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8873                                 0x00000000, 0x0000ff00};
8874
8875     const float vertices[] = {
8876         64,     64,     0.1,
8877         128,    64,     0.1,
8878         192,    64,     0.1,
8879         256,    64,     0.1,
8880         320,    64,     0.1,
8881         384,    64,     0.1,
8882         448,    64,     0.1,
8883         512,    64,     0.1,
8884     };
8885
8886     /* 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 */
8887     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;
8888     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;
8889     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;
8890     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;
8891
8892     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;
8893     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;
8894     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;
8895     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;
8896
8897     memset(&caps, 0, sizeof(caps));
8898     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8899     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8900     if(caps.MaxPointSize < 32.0) {
8901         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8902         return;
8903     }
8904
8905     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8906     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8907     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8908     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8909     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8910     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8911     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8912     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8913
8914     hr = IDirect3DDevice9_BeginScene(device);
8915     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8916     if (SUCCEEDED(hr))
8917     {
8918         ptsize = 15.0;
8919         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8920         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8921         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8922         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8923
8924         ptsize = 31.0;
8925         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8926         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8927         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8928         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8929
8930         ptsize = 30.75;
8931         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8932         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8933         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8934         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8935
8936         if (caps.MaxPointSize >= 63.0)
8937         {
8938             ptsize = 63.0;
8939             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8940             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8941             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8942             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8943
8944             ptsize = 62.75;
8945             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8946             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8947             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8948             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8949         }
8950
8951         ptsize = 1.0;
8952         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8953         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8954         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8955         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8956
8957         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8958         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8959         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8960         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8961
8962         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8963         ptsize = 15.0;
8964         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8965         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8966         ptsize = 1.0;
8967         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8968         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8969         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8970         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8971
8972         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8973         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8974
8975         /* pointsize < pointsize_min < pointsize_max?
8976          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8977         ptsize = 1.0;
8978         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8979         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8980         ptsize = 15.0;
8981         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8982         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8983         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8984         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8985
8986         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8987         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8988
8989         hr = IDirect3DDevice9_EndScene(device);
8990         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8991     }
8992
8993     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8994     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8995     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8996
8997     if (caps.MaxPointSize >= 63.0)
8998     {
8999         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
9000         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
9001     }
9002
9003     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
9004     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
9005     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
9006     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
9007     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
9008
9009     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9010
9011     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
9012      * generates texture coordinates for the point(result: Yes, it does)
9013      *
9014      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
9015      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
9016      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
9017      */
9018     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
9019     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9020
9021     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
9022     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9023     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9024     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9025     memset(&lr, 0, sizeof(lr));
9026     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
9027     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9028     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
9029     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9030     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9031     memset(&lr, 0, sizeof(lr));
9032     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
9033     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9034     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
9035     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9036     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9037     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9038     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9039     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9040     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9041     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9042     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9043     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9044     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9045     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9046     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9047     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9048     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9049     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9050     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9051
9052     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
9053     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9054     ptsize = 32.0;
9055     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9056     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9057
9058     hr = IDirect3DDevice9_BeginScene(device);
9059     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9060     if(SUCCEEDED(hr))
9061     {
9062         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9063         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9064         hr = IDirect3DDevice9_EndScene(device);
9065         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9066     }
9067
9068     color = getPixelColor(device, 64-4, 64-4);
9069     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
9070     color = getPixelColor(device, 64-4, 64+4);
9071     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
9072     color = getPixelColor(device, 64+4, 64+4);
9073     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
9074     color = getPixelColor(device, 64+4, 64-4);
9075     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
9076     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9077
9078     U(matrix).m[0][0] =  1.0f / 64.0f;
9079     U(matrix).m[1][1] = -1.0f / 64.0f;
9080     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
9081     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
9082
9083     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
9084     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
9085
9086     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
9087             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
9088     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
9089
9090     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
9091     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9092     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
9093     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
9094
9095     hr = IDirect3DDevice9_BeginScene(device);
9096     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9097     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9098     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9099     hr = IDirect3DDevice9_EndScene(device);
9100     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9101
9102     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
9103     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
9104     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9105     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9106     IDirect3DSurface9_Release(backbuffer);
9107     IDirect3DSurface9_Release(rt);
9108
9109     color = getPixelColor(device, 64-4, 64-4);
9110     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
9111             "Expected color 0x00ff0000, got 0x%08x.\n", color);
9112     color = getPixelColor(device, 64+4, 64-4);
9113     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
9114             "Expected color 0x00ffff00, got 0x%08x.\n", color);
9115     color = getPixelColor(device, 64-4, 64+4);
9116     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
9117             "Expected color 0x00000000, got 0x%08x.\n", color);
9118     color = getPixelColor(device, 64+4, 64+4);
9119     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9120             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9121
9122     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9123     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9124
9125     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9126     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9127     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9128     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9129     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9130     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9131     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9132     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9133     IDirect3DTexture9_Release(tex1);
9134     IDirect3DTexture9_Release(tex2);
9135
9136     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9137     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9138     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9139     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9140     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9141     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9142 }
9143
9144 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9145 {
9146     static const DWORD vshader_code[] =
9147     {
9148         0xfffe0300,                                                             /* vs_3_0                     */
9149         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0            */
9150         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0            */
9151         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                 */
9152         0x0000ffff                                                              /* end                        */
9153     };
9154     static const DWORD pshader_code1[] =
9155     {
9156         0xffff0300,                                                             /* ps_3_0                     */
9157         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9158         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
9159         0x0000ffff                                                              /* end                        */
9160     };
9161     static const DWORD pshader_code2[] =
9162     {
9163         0xffff0300,                                                             /* ps_3_0                     */
9164         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9165         0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
9166         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
9167         0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1                */
9168         0x0000ffff                                                              /* end                        */
9169     };
9170
9171     HRESULT hr;
9172     IDirect3DVertexShader9 *vs;
9173     IDirect3DPixelShader9 *ps1, *ps2;
9174     IDirect3DTexture9 *tex1, *tex2;
9175     IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
9176     D3DCAPS9 caps;
9177     DWORD color;
9178     UINT i, j;
9179     float quad[] = {
9180        -1.0,   -1.0,    0.1,
9181         1.0,   -1.0,    0.1,
9182        -1.0,    1.0,    0.1,
9183         1.0,    1.0,    0.1,
9184     };
9185     float texquad[] = {
9186        -1.0,   -1.0,    0.1,    0.0,    0.0,
9187         0.0,   -1.0,    0.1,    1.0,    0.0,
9188        -1.0,    1.0,    0.1,    0.0,    1.0,
9189         0.0,    1.0,    0.1,    1.0,    1.0,
9190
9191         0.0,   -1.0,    0.1,    0.0,    0.0,
9192         1.0,   -1.0,    0.1,    1.0,    0.0,
9193         0.0,    1.0,    0.1,    0.0,    1.0,
9194         1.0,    1.0,    0.1,    1.0,    1.0,
9195     };
9196
9197     memset(&caps, 0, sizeof(caps));
9198     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9199     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9200     if(caps.NumSimultaneousRTs < 2) {
9201         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9202         return;
9203     }
9204
9205     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9206     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9207
9208     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
9209             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
9210     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
9211
9212     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9213             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9214     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9215     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9216             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9217     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9218     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
9219     ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
9220     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
9221     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9222     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
9223     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9224
9225     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9226     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9227     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9228     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9229     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9230     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9231
9232     hr = IDirect3DDevice9_SetVertexShader(device, vs);
9233     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9234     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9235     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9236     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9237     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9238     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9239     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9240
9241     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
9242     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9243     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9244     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9245     color = getPixelColorFromSurface(readback, 8, 8);
9246     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9247             "Expected color 0x000000ff, got 0x%08x.\n", color);
9248     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9249     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9250     color = getPixelColorFromSurface(readback, 8, 8);
9251     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9252             "Expected color 0x000000ff, got 0x%08x.\n", color);
9253
9254     /* Render targets not written by the pixel shader should be unmodified. */
9255     hr = IDirect3DDevice9_SetPixelShader(device, ps1);
9256     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9257     hr = IDirect3DDevice9_BeginScene(device);
9258     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9259     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9260     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9261     hr = IDirect3DDevice9_EndScene(device);
9262     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9263     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9264     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9265     color = getPixelColorFromSurface(readback, 8, 8);
9266     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9267             "Expected color 0xff00ff00, got 0x%08x.\n", color);
9268     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9269     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9270     for (i = 6; i < 10; ++i)
9271     {
9272         for (j = 6; j < 10; ++j)
9273         {
9274             color = getPixelColorFromSurface(readback, j, i);
9275             ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9276                     "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
9277         }
9278     }
9279
9280     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9281     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9282     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9283     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9284     color = getPixelColorFromSurface(readback, 8, 8);
9285     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9286             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9287     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9288     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9289     color = getPixelColorFromSurface(readback, 8, 8);
9290     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9291             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9292
9293     hr = IDirect3DDevice9_SetPixelShader(device, ps2);
9294     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9295
9296     hr = IDirect3DDevice9_BeginScene(device);
9297     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9298     if(SUCCEEDED(hr)) {
9299         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9300         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9301
9302         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9303         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9304         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9305         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9306         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9307         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9308         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9309         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9310         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9311         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9312
9313         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9314         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9315         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9316         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9317
9318         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9319         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9320         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9321         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9322
9323         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9324         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9325
9326         hr = IDirect3DDevice9_EndScene(device);
9327         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9328     }
9329
9330     color = getPixelColor(device, 160, 240);
9331     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9332     color = getPixelColor(device, 480, 240);
9333     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9334     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9335
9336     IDirect3DPixelShader9_Release(ps2);
9337     IDirect3DPixelShader9_Release(ps1);
9338     IDirect3DVertexShader9_Release(vs);
9339     IDirect3DTexture9_Release(tex1);
9340     IDirect3DTexture9_Release(tex2);
9341     IDirect3DSurface9_Release(surf1);
9342     IDirect3DSurface9_Release(surf2);
9343     IDirect3DSurface9_Release(backbuf);
9344     IDirect3DSurface9_Release(readback);
9345 }
9346
9347 struct formats {
9348     const char *fmtName;
9349     D3DFORMAT textureFormat;
9350     DWORD resultColorBlending;
9351     DWORD resultColorNoBlending;
9352 };
9353
9354 static const struct formats test_formats[] = {
9355   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9356   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9357   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9358   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9359   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9360   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9361   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9362   { NULL, 0 }
9363 };
9364
9365 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9366 {
9367     HRESULT hr;
9368     IDirect3DTexture9 *offscreenTexture = NULL;
9369     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9370     IDirect3D9 *d3d = NULL;
9371     DWORD color;
9372     DWORD r0, g0, b0, r1, g1, b1;
9373     int fmt_index;
9374
9375     static const float quad[][5] = {
9376         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9377         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
9378         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9379         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
9380     };
9381
9382     /* Quad with R=0x10, G=0x20 */
9383     static const struct vertex quad1[] = {
9384         {-1.0f, -1.0f, 0.1f, 0x80102000},
9385         {-1.0f,  1.0f, 0.1f, 0x80102000},
9386         { 1.0f, -1.0f, 0.1f, 0x80102000},
9387         { 1.0f,  1.0f, 0.1f, 0x80102000},
9388     };
9389
9390     /* Quad with R=0x20, G=0x10 */
9391     static const struct vertex quad2[] = {
9392         {-1.0f, -1.0f, 0.1f, 0x80201000},
9393         {-1.0f,  1.0f, 0.1f, 0x80201000},
9394         { 1.0f, -1.0f, 0.1f, 0x80201000},
9395         { 1.0f,  1.0f, 0.1f, 0x80201000},
9396     };
9397
9398     IDirect3DDevice9_GetDirect3D(device, &d3d);
9399
9400     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9401     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9402     if(!backbuffer) {
9403         goto out;
9404     }
9405
9406     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9407     {
9408         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9409
9410         if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9411                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
9412         {
9413             skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
9414             continue;
9415         }
9416
9417         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9418         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9419
9420         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9421         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9422         if(!offscreenTexture) {
9423             continue;
9424         }
9425
9426         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9427         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9428         if(!offscreen) {
9429             continue;
9430         }
9431
9432         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9433         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9434
9435         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9436         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9437         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9438         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9439         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9440         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9441         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9442         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9443         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9444         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9445
9446         /* Below we will draw two quads with different colors and try to blend them together.
9447          * The result color is compared with the expected outcome.
9448          */
9449         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9450             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9451             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9452             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9453             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9454
9455             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9456             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9457
9458             /* Draw a quad using color 0x0010200 */
9459             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9460             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9461             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9462             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9463             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9464             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9465
9466             /* Draw a quad using color 0x0020100 */
9467             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9468             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9469             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9470             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9471             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9472             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9473
9474             /* We don't want to blend the result on the backbuffer */
9475             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9476             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9477
9478             /* Prepare rendering the 'blended' texture quad to the backbuffer */
9479             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9480             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9481             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9482             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9483
9484             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9485             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9486
9487             /* This time with the texture */
9488             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9489             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9490
9491             IDirect3DDevice9_EndScene(device);
9492         }
9493
9494         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9495             /* Compare the color of the center quad with our expectation */
9496             color = getPixelColor(device, 320, 240);
9497             r0 = (color & 0x00ff0000) >> 16;
9498             g0 = (color & 0x0000ff00) >>  8;
9499             b0 = (color & 0x000000ff) >>  0;
9500
9501             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9502             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9503             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9504
9505             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9506                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9507                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9508                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9509         } else {
9510             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9511              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9512              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9513             color = getPixelColor(device, 320, 240);
9514             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);
9515         }
9516         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9517
9518         IDirect3DDevice9_SetTexture(device, 0, NULL);
9519         if(offscreenTexture) {
9520             IDirect3DTexture9_Release(offscreenTexture);
9521         }
9522         if(offscreen) {
9523             IDirect3DSurface9_Release(offscreen);
9524         }
9525     }
9526
9527 out:
9528     /* restore things */
9529     if(backbuffer) {
9530         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9531         IDirect3DSurface9_Release(backbuffer);
9532     }
9533 }
9534
9535 static void tssargtemp_test(IDirect3DDevice9 *device)
9536 {
9537     HRESULT hr;
9538     DWORD color;
9539     static const struct vertex quad[] = {
9540         {-1.0,     -1.0,    0.1,    0x00ff0000},
9541         { 1.0,     -1.0,    0.1,    0x00ff0000},
9542         {-1.0,      1.0,    0.1,    0x00ff0000},
9543         { 1.0,      1.0,    0.1,    0x00ff0000}
9544     };
9545     D3DCAPS9 caps;
9546
9547     memset(&caps, 0, sizeof(caps));
9548     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9549     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9550     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9551         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9552         return;
9553     }
9554
9555     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9556     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9557
9558     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9559     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9560     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9561     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9562
9563     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9564     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9565     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9566     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9567     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9568     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9569
9570     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9571     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9572     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9573     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9574     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9575     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9576
9577     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9578     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9579
9580     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9581     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9582     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9583     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9584
9585     hr = IDirect3DDevice9_BeginScene(device);
9586     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9587     if(SUCCEEDED(hr)) {
9588         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9589         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9590         hr = IDirect3DDevice9_EndScene(device);
9591         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9592     }
9593     color = getPixelColor(device, 320, 240);
9594     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9595     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9596
9597     /* Set stage 1 back to default */
9598     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9599     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9600     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9601     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9602     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9603     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9604     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9605     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9606     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9607     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9608 }
9609
9610 struct testdata
9611 {
9612     DWORD idxVertex; /* number of instances in the first stream */
9613     DWORD idxColor; /* number of instances in the second stream */
9614     DWORD idxInstance; /* should be 1 ?? */
9615     DWORD color1; /* color 1 instance */
9616     DWORD color2; /* color 2 instance */
9617     DWORD color3; /* color 3 instance */
9618     DWORD color4; /* color 4 instance */
9619     WORD strVertex; /* specify which stream to use 0-2*/
9620     WORD strColor;
9621     WORD strInstance;
9622 };
9623
9624 static const struct testdata testcases[]=
9625 {
9626     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9627     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9628     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9629     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9630     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  4 */
9631     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9632     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9633     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9634     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  8 */
9635     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /*  9 */
9636     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9637     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9638     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9639     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9640 /*
9641     This draws one instance on some machines, no instance on others
9642     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9643 */
9644 /*
9645     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9646     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9647 */
9648 };
9649
9650 /* Drawing Indexed Geometry with instances*/
9651 static void stream_test(IDirect3DDevice9 *device)
9652 {
9653     IDirect3DVertexBuffer9 *vb = NULL;
9654     IDirect3DVertexBuffer9 *vb2 = NULL;
9655     IDirect3DVertexBuffer9 *vb3 = NULL;
9656     IDirect3DIndexBuffer9 *ib = NULL;
9657     IDirect3DVertexDeclaration9 *pDecl = NULL;
9658     IDirect3DVertexShader9 *shader = NULL;
9659     HRESULT hr;
9660     BYTE *data;
9661     DWORD color;
9662     DWORD ind;
9663     unsigned i;
9664
9665     const DWORD shader_code[] =
9666     {
9667         0xfffe0101,                                     /* vs_1_1 */
9668         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9669         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9670         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9671         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9672         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9673         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9674         0x0000ffff
9675     };
9676
9677     const float quad[][3] =
9678     {
9679         {-0.5f, -0.5f,  1.1f}, /*0 */
9680         {-0.5f,  0.5f,  1.1f}, /*1 */
9681         { 0.5f, -0.5f,  1.1f}, /*2 */
9682         { 0.5f,  0.5f,  1.1f}, /*3 */
9683     };
9684
9685     const float vertcolor[][4] =
9686     {
9687         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9688         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9689         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9690         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9691     };
9692
9693     /* 4 position for 4 instances */
9694     const float instancepos[][3] =
9695     {
9696         {-0.6f,-0.6f, 0.0f},
9697         { 0.6f,-0.6f, 0.0f},
9698         { 0.6f, 0.6f, 0.0f},
9699         {-0.6f, 0.6f, 0.0f},
9700     };
9701
9702     short indices[] = {0, 1, 2, 1, 2, 3};
9703
9704     D3DVERTEXELEMENT9 decl[] =
9705     {
9706         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9707         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9708         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9709         D3DDECL_END()
9710     };
9711
9712     /* set the default value because it isn't done in wine? */
9713     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9714     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9715
9716     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9717     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9718     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9719
9720     /* check wrong cases */
9721     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9722     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9723     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9724     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9725     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9726     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9727     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9728     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9729     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9730     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9731     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9732     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9733     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9734     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9735     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9736     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9737     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9738     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9739     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9740     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9741
9742     /* set the default value back */
9743     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9744     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9745
9746     /* create all VertexBuffers*/
9747     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9748     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9749     if(!vb) {
9750         skip("Failed to create a vertex buffer\n");
9751         return;
9752     }
9753     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9754     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9755     if(!vb2) {
9756         skip("Failed to create a vertex buffer\n");
9757         goto out;
9758     }
9759     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9760     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9761     if(!vb3) {
9762         skip("Failed to create a vertex buffer\n");
9763         goto out;
9764     }
9765
9766     /* create IndexBuffer*/
9767     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9768     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9769     if(!ib) {
9770         skip("Failed to create a index buffer\n");
9771         goto out;
9772     }
9773
9774     /* copy all Buffers (Vertex + Index)*/
9775     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9776     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9777     memcpy(data, quad, sizeof(quad));
9778     hr = IDirect3DVertexBuffer9_Unlock(vb);
9779     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9780     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9781     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9782     memcpy(data, vertcolor, sizeof(vertcolor));
9783     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9784     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9785     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9786     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9787     memcpy(data, instancepos, sizeof(instancepos));
9788     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9789     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9790     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9791     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9792     memcpy(data, indices, sizeof(indices));
9793     hr = IDirect3DIndexBuffer9_Unlock(ib);
9794     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9795
9796     /* create VertexShader */
9797     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9798     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9799     if(!shader) {
9800         skip("Failed to create a vetex shader\n");
9801         goto out;
9802     }
9803
9804     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9805     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9806
9807     hr = IDirect3DDevice9_SetIndices(device, ib);
9808     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9809
9810     /* run all tests */
9811     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9812     {
9813         struct testdata act = testcases[i];
9814         decl[0].Stream = act.strVertex;
9815         decl[1].Stream = act.strColor;
9816         decl[2].Stream = act.strInstance;
9817         /* create VertexDeclarations */
9818         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9819         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9820
9821         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9822         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9823
9824         hr = IDirect3DDevice9_BeginScene(device);
9825         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9826         if(SUCCEEDED(hr))
9827         {
9828             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9829             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9830
9831             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9832             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9833             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9834             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9835
9836             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9837             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9838             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9839             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9840
9841             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9842             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9843             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9844             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9845
9846             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9847             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9848             hr = IDirect3DDevice9_EndScene(device);
9849             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9850
9851             /* set all StreamSource && StreamSourceFreq back to default */
9852             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9853             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9854             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9855             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9856             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9857             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9858             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9859             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9860             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9861             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9862             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9863             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9864         }
9865
9866         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9867         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9868
9869         color = getPixelColor(device, 160, 360);
9870         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9871         color = getPixelColor(device, 480, 360);
9872         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9873         color = getPixelColor(device, 480, 120);
9874         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9875         color = getPixelColor(device, 160, 120);
9876         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9877
9878         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9879         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9880     }
9881
9882     hr = IDirect3DDevice9_SetIndices(device, NULL);
9883     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9884
9885 out:
9886     if(vb) IDirect3DVertexBuffer9_Release(vb);
9887     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9888     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9889     if(ib)IDirect3DIndexBuffer9_Release(ib);
9890     if(shader)IDirect3DVertexShader9_Release(shader);
9891 }
9892
9893 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9894     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9895     IDirect3DTexture9 *dsttex = NULL;
9896     HRESULT hr;
9897     DWORD color;
9898     D3DRECT r1 = {0,  0,  50,  50 };
9899     D3DRECT r2 = {50, 0,  100, 50 };
9900     D3DRECT r3 = {50, 50, 100, 100};
9901     D3DRECT r4 = {0,  50,  50, 100};
9902     const float quad[] = {
9903         -1.0,   -1.0,   0.1,    0.0,    0.0,
9904          1.0,   -1.0,   0.1,    1.0,    0.0,
9905         -1.0,    1.0,   0.1,    0.0,    1.0,
9906          1.0,    1.0,   0.1,    1.0,    1.0,
9907     };
9908
9909     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9910     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9911
9912     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9913     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9914     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9915     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9916
9917     if(!src || !dsttex) {
9918         skip("One or more test resources could not be created\n");
9919         goto cleanup;
9920     }
9921
9922     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9923     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9924
9925     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9926     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9927
9928     /* Clear the StretchRect destination for debugging */
9929     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9930     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9931     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9932     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9933
9934     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9935     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9936
9937     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9938     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9939     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9940     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9941     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9942     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9943     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9944     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9945
9946     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9947      * the target -> texture GL blit path
9948      */
9949     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9950     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9951     IDirect3DSurface9_Release(dst);
9952
9953     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9954     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9955
9956     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9957     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9958     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9959     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9960     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9961     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9962     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9963     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9964
9965     hr = IDirect3DDevice9_BeginScene(device);
9966     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9967     if(SUCCEEDED(hr)) {
9968         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9969         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9970         hr = IDirect3DDevice9_EndScene(device);
9971         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9972     }
9973
9974     color = getPixelColor(device, 160, 360);
9975     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9976     color = getPixelColor(device, 480, 360);
9977     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9978     color = getPixelColor(device, 480, 120);
9979     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9980     color = getPixelColor(device, 160, 120);
9981     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9982     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9983     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9984
9985     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9986     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9987     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9988     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9989
9990 cleanup:
9991     if(src) IDirect3DSurface9_Release(src);
9992     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9993     if(dsttex) IDirect3DTexture9_Release(dsttex);
9994 }
9995
9996 static void texop_test(IDirect3DDevice9 *device)
9997 {
9998     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9999     IDirect3DTexture9 *texture = NULL;
10000     D3DLOCKED_RECT locked_rect;
10001     D3DCOLOR color;
10002     D3DCAPS9 caps;
10003     HRESULT hr;
10004     unsigned i;
10005
10006     static const struct {
10007         float x, y, z;
10008         float s, t;
10009         D3DCOLOR diffuse;
10010     } quad[] = {
10011         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10012         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10013         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10014         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
10015     };
10016
10017     static const D3DVERTEXELEMENT9 decl_elements[] = {
10018         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10019         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
10020         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
10021         D3DDECL_END()
10022     };
10023
10024     static const struct {
10025         D3DTEXTUREOP op;
10026         const char *name;
10027         DWORD caps_flag;
10028         D3DCOLOR result;
10029     } test_data[] = {
10030         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10031         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
10032         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
10033         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
10034         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10035         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10036         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
10037         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10038         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10039         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10040         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10041         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
10042         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
10043         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10044         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10045         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
10046         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
10047         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10048         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
10049         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
10050         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
10051         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
10052         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
10053     };
10054
10055     memset(&caps, 0, sizeof(caps));
10056     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10057     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10058
10059     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
10060     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
10061     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
10062     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
10063
10064     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10065     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10066     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10067     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10068     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
10069     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10070     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10071     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10072     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10073
10074     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
10075     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10076     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10077     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10078     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10079     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10080
10081     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10082     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10083
10084     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10085     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10086     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
10087     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10088     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
10089     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10090
10091     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10092     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10093
10094     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
10095     {
10096         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
10097         {
10098             skip("tex operation %s not supported\n", test_data[i].name);
10099             continue;
10100         }
10101
10102         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
10103         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
10104
10105         hr = IDirect3DDevice9_BeginScene(device);
10106         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10107
10108         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10109         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10110
10111         hr = IDirect3DDevice9_EndScene(device);
10112         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10113
10114         color = getPixelColor(device, 320, 240);
10115         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
10116                 test_data[i].name, color, test_data[i].result);
10117
10118         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10119         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10120     }
10121
10122     if (texture) IDirect3DTexture9_Release(texture);
10123     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
10124 }
10125
10126 static void yuv_color_test(IDirect3DDevice9 *device) {
10127     HRESULT hr;
10128     IDirect3DSurface9 *surface = NULL, *target = NULL;
10129     unsigned int fmt, i;
10130     D3DFORMAT format;
10131     const char *fmt_string;
10132     D3DLOCKED_RECT lr;
10133     IDirect3D9 *d3d;
10134     HRESULT color;
10135     DWORD ref_color_left, ref_color_right;
10136
10137     struct {
10138         DWORD in;           /* The input color */
10139         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
10140         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
10141         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
10142         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
10143     } test_data[] = {
10144     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
10145      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
10146      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
10147      * that
10148      */
10149       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
10150       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
10151       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
10152       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
10153       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
10154       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
10155       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
10156       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
10157       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
10158       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
10159       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
10160       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
10161       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
10162       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
10163
10164       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
10165       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
10166       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
10167       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
10168     };
10169
10170     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
10171     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
10172     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
10173     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
10174
10175     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
10176     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10177
10178     for(fmt = 0; fmt < 2; fmt++) {
10179         if(fmt == 0) {
10180             format = D3DFMT_UYVY;
10181             fmt_string = "D3DFMT_UYVY";
10182         } else {
10183             format = D3DFMT_YUY2;
10184             fmt_string = "D3DFMT_YUY2";
10185         }
10186
10187         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
10188                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
10189                        */
10190         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
10191                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
10192             skip("%s is not supported\n", fmt_string);
10193             continue;
10194         }
10195
10196         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
10197         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
10198         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
10199
10200         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
10201             if(fmt == 0) {
10202                 ref_color_left = test_data[i].uyvy_left;
10203                 ref_color_right = test_data[i].uyvy_right;
10204             } else {
10205                 ref_color_left = test_data[i].yuy2_left;
10206                 ref_color_right = test_data[i].yuy2_right;
10207             }
10208
10209             memset(&lr, 0, sizeof(lr));
10210             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
10211             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
10212             *((DWORD *) lr.pBits) = test_data[i].in;
10213             hr = IDirect3DSurface9_UnlockRect(surface);
10214             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10215
10216             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10217             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10218             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10219             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10220
10221             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10222              * prevent running into precision problems, read a far left and far right pixel. In the future we may
10223              * want to add tests for the filtered pixels as well.
10224              *
10225              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10226              * differently, so we need a max diff of 16
10227              */
10228             color = getPixelColor(device, 40, 240);
10229
10230             /* Newer versions of the Nvidia Windows driver mix up the U and V channels, breaking all the tests
10231              * where U != V. Skip the entire test if this bug in this case
10232              */
10233             if (broken(test_data[i].in == 0xff000000 && color == 0x00008800 && format == D3DFMT_UYVY))
10234             {
10235                 skip("Nvidia channel confusion bug detected, skipping YUV tests\n");
10236                 IDirect3DSurface9_Release(surface);
10237                 goto out;
10238             }
10239
10240             ok(color_match(color, ref_color_left, 18),
10241                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10242                test_data[i].in, color, ref_color_left, fmt_string);
10243             color = getPixelColor(device, 600, 240);
10244             ok(color_match(color, ref_color_right, 18),
10245                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10246                test_data[i].in, color, ref_color_right, fmt_string);
10247             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10248             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10249         }
10250         IDirect3DSurface9_Release(surface);
10251     }
10252
10253 out:
10254     IDirect3DSurface9_Release(target);
10255     IDirect3D9_Release(d3d);
10256 }
10257
10258 static void texop_range_test(IDirect3DDevice9 *device)
10259 {
10260     static const struct {
10261         float x, y, z;
10262         D3DCOLOR diffuse;
10263     } quad[] = {
10264         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10265         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10266         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10267         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10268     };
10269     HRESULT hr;
10270     IDirect3DTexture9 *texture;
10271     D3DLOCKED_RECT locked_rect;
10272     D3DCAPS9 caps;
10273     DWORD color;
10274
10275     /* We need ADD and SUBTRACT operations */
10276     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10277     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10278     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10279         skip("D3DTOP_ADD is not supported, skipping value range test\n");
10280         return;
10281     }
10282     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10283         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10284         return;
10285     }
10286
10287     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10288     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10289     /* Stage 1: result = diffuse(=1.0) + diffuse
10290      * stage 2: result = result - tfactor(= 0.5)
10291      */
10292     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10293     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10294     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10295     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10296     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10297     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10298     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10299     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10300     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10301     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10302     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10303     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10304     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10305     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10306
10307     hr = IDirect3DDevice9_BeginScene(device);
10308     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10309     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10310     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10311     hr = IDirect3DDevice9_EndScene(device);
10312     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10313
10314     color = getPixelColor(device, 320, 240);
10315     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10316        color);
10317     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10318     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10319
10320     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10321     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10322     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10323     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10324     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10325     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10326     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10327     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10328     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10329
10330     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10331      * stage 2: result = result + diffuse(1.0)
10332      */
10333     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10334     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10335     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10336     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10337     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10338     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10339     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10340     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10341     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10342     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10343     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10344     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10345     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10346     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10347
10348     hr = IDirect3DDevice9_BeginScene(device);
10349     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10350     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10351     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10352     hr = IDirect3DDevice9_EndScene(device);
10353     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10354
10355     color = getPixelColor(device, 320, 240);
10356     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10357        color);
10358     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10359     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10360
10361     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10362     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10363     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10364     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10365     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10366     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10367     IDirect3DTexture9_Release(texture);
10368 }
10369
10370 static void alphareplicate_test(IDirect3DDevice9 *device) {
10371     struct vertex quad[] = {
10372         { -1.0,    -1.0,    0.1,    0x80ff00ff },
10373         {  1.0,    -1.0,    0.1,    0x80ff00ff },
10374         { -1.0,     1.0,    0.1,    0x80ff00ff },
10375         {  1.0,     1.0,    0.1,    0x80ff00ff },
10376     };
10377     HRESULT hr;
10378     DWORD color;
10379
10380     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10381     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10382
10383     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10384     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10385
10386     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10387     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10388     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10389     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10390
10391     hr = IDirect3DDevice9_BeginScene(device);
10392     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10393     if(SUCCEEDED(hr)) {
10394         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10395         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10396         hr = IDirect3DDevice9_EndScene(device);
10397         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10398     }
10399
10400     color = getPixelColor(device, 320, 240);
10401     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10402        color);
10403     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10404     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10405
10406     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10407     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10408
10409 }
10410
10411 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10412     HRESULT hr;
10413     D3DCAPS9 caps;
10414     DWORD color;
10415     struct vertex quad[] = {
10416         { -1.0,    -1.0,    0.1,    0x408080c0 },
10417         {  1.0,    -1.0,    0.1,    0x408080c0 },
10418         { -1.0,     1.0,    0.1,    0x408080c0 },
10419         {  1.0,     1.0,    0.1,    0x408080c0 },
10420     };
10421
10422     memset(&caps, 0, sizeof(caps));
10423     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10424     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10425     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10426         skip("D3DTOP_DOTPRODUCT3 not supported\n");
10427         return;
10428     }
10429
10430     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10431     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10432
10433     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10434     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10435
10436     /* dp3_x4 r0, diffuse_bias, tfactor_bias
10437      * mov r0.a, diffuse.a
10438      * mov r0, r0.a
10439      *
10440      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10441      * 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
10442      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10443      */
10444     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10445     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10446     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10447     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10448     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10449     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10450     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10451     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10452     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10453     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10454     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10455     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10456     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10457     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10458     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10459     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10460     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10461     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10462
10463     hr = IDirect3DDevice9_BeginScene(device);
10464     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10465     if(SUCCEEDED(hr)) {
10466         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10467         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10468         hr = IDirect3DDevice9_EndScene(device);
10469         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10470     }
10471
10472     color = getPixelColor(device, 320, 240);
10473     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10474        color);
10475     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10476     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10477
10478     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10479     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10480     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10481     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10482     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10483     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10484 }
10485
10486 static void zwriteenable_test(IDirect3DDevice9 *device) {
10487     HRESULT hr;
10488     DWORD color;
10489     struct vertex quad1[] = {
10490         { -1.0,  -1.0,  0.1,    0x00ff0000},
10491         { -1.0,   1.0,  0.1,    0x00ff0000},
10492         {  1.0,  -1.0,  0.1,    0x00ff0000},
10493         {  1.0,   1.0,  0.1,    0x00ff0000},
10494     };
10495     struct vertex quad2[] = {
10496         { -1.0,  -1.0,  0.9,    0x0000ff00},
10497         { -1.0,   1.0,  0.9,    0x0000ff00},
10498         {  1.0,  -1.0,  0.9,    0x0000ff00},
10499         {  1.0,   1.0,  0.9,    0x0000ff00},
10500     };
10501
10502     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10503     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10504
10505     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10506     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10507     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10508     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10509     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10510     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10511     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10512     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10513
10514     hr = IDirect3DDevice9_BeginScene(device);
10515     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10516     if(SUCCEEDED(hr)) {
10517         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10518          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10519          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10520          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10521          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10522          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10523          */
10524         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10525         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10526         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10527         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10528         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10529         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10530
10531         hr = IDirect3DDevice9_EndScene(device);
10532         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10533     }
10534
10535     color = getPixelColor(device, 320, 240);
10536     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10537        color);
10538     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10539     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10540
10541     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10542     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10543 }
10544
10545 static void alphatest_test(IDirect3DDevice9 *device) {
10546 #define ALPHATEST_PASSED 0x0000ff00
10547 #define ALPHATEST_FAILED 0x00ff0000
10548     struct {
10549         D3DCMPFUNC  func;
10550         DWORD       color_less;
10551         DWORD       color_equal;
10552         DWORD       color_greater;
10553     } testdata[] = {
10554         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10555         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10556         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10557         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10558         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10559         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10560         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10561         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10562     };
10563     unsigned int i, j;
10564     HRESULT hr;
10565     DWORD color;
10566     struct vertex quad[] = {
10567         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10568         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10569         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10570         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10571     };
10572     D3DCAPS9 caps;
10573
10574     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10575     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10576     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10577     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10578
10579     for(j = 0; j < 2; j++) {
10580         if(j == 1) {
10581             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10582              * the alpha test either for performance reasons(floating point RTs) or to work
10583              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10584              * codepath for ffp and shader in this case, and the test should cover both
10585              */
10586             IDirect3DPixelShader9 *ps;
10587             DWORD shader_code[] = {
10588                 0xffff0101,                                 /* ps_1_1           */
10589                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10590                 0x0000ffff                                  /* end              */
10591             };
10592             memset(&caps, 0, sizeof(caps));
10593             hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10594             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10595             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10596                 break;
10597             }
10598
10599             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10600             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10601             hr = IDirect3DDevice9_SetPixelShader(device, ps);
10602             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10603             IDirect3DPixelShader9_Release(ps);
10604         }
10605
10606         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10607             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10608             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10609
10610             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10611             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10612             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10613             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10614             hr = IDirect3DDevice9_BeginScene(device);
10615             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10616             if(SUCCEEDED(hr)) {
10617                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10618                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10619                 hr = IDirect3DDevice9_EndScene(device);
10620                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10621             }
10622             color = getPixelColor(device, 320, 240);
10623             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10624             color, testdata[i].color_less, testdata[i].func);
10625             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10626             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10627
10628             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10629             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10630             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10631             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10632             hr = IDirect3DDevice9_BeginScene(device);
10633             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10634             if(SUCCEEDED(hr)) {
10635                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10636                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10637                 hr = IDirect3DDevice9_EndScene(device);
10638                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10639             }
10640             color = getPixelColor(device, 320, 240);
10641             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10642             color, testdata[i].color_equal, testdata[i].func);
10643             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10644             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10645
10646             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10647             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10648             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10649             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10650             hr = IDirect3DDevice9_BeginScene(device);
10651             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10652             if(SUCCEEDED(hr)) {
10653                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10654                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10655                 hr = IDirect3DDevice9_EndScene(device);
10656                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10657             }
10658             color = getPixelColor(device, 320, 240);
10659             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10660             color, testdata[i].color_greater, testdata[i].func);
10661             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10662             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10663         }
10664     }
10665
10666     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10667     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10668     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10669     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10670 }
10671
10672 static void sincos_test(IDirect3DDevice9 *device) {
10673     const DWORD sin_shader_code[] = {
10674         0xfffe0200,                                                                 /* vs_2_0                       */
10675         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10676         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10677         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10678         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10679         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10680         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10681         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10682         0x0000ffff                                                                  /* end                          */
10683     };
10684     const DWORD cos_shader_code[] = {
10685         0xfffe0200,                                                                 /* vs_2_0                       */
10686         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10687         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10688         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10689         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10690         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10691         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10692         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10693         0x0000ffff                                                                  /* end                          */
10694     };
10695     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10696     HRESULT hr;
10697     struct {
10698         float x, y, z;
10699     } data[1280];
10700     unsigned int i;
10701     float sincosc1[4] = {D3DSINCOSCONST1};
10702     float sincosc2[4] = {D3DSINCOSCONST2};
10703
10704     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10705     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10706
10707     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10708     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10709     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10710     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10711     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10712     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10713     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10714     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10715     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10716     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10717
10718     /* Generate a point from -1 to 1 every 0.5 pixels */
10719     for(i = 0; i < 1280; i++) {
10720         data[i].x = (-640.0 + i) / 640.0;
10721         data[i].y = 0.0;
10722         data[i].z = 0.1;
10723     }
10724
10725     hr = IDirect3DDevice9_BeginScene(device);
10726     if(SUCCEEDED(hr)) {
10727         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10728         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10729         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10730         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10731
10732         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10733         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10734         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10735         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10736
10737         hr = IDirect3DDevice9_EndScene(device);
10738         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10739     }
10740     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10741     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10742     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10743
10744     IDirect3DDevice9_SetVertexShader(device, NULL);
10745     IDirect3DVertexShader9_Release(sin_shader);
10746     IDirect3DVertexShader9_Release(cos_shader);
10747 }
10748
10749 static void loop_index_test(IDirect3DDevice9 *device) {
10750     const DWORD shader_code[] = {
10751         0xfffe0200,                                                 /* vs_2_0                   */
10752         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10753         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10754         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10755         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10756         0x0000001d,                                                 /* endloop                  */
10757         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10758         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10759         0x0000ffff                                                  /* END                      */
10760     };
10761     IDirect3DVertexShader9 *shader;
10762     HRESULT hr;
10763     DWORD color;
10764     const float quad[] = {
10765         -1.0,   -1.0,   0.1,
10766          1.0,   -1.0,   0.1,
10767         -1.0,    1.0,   0.1,
10768          1.0,    1.0,   0.1
10769     };
10770     const float zero[4] = {0, 0, 0, 0};
10771     const float one[4] = {1, 1, 1, 1};
10772     int i0[4] = {2, 10, -3, 0};
10773     float values[4];
10774
10775     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10776     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10777     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10778     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10779     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10780     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10781     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10782     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10783
10784     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10785     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10786     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10787     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10788     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10789     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10790     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10791     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10792     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10793     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10794     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10795     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10796     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10797     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10798     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10799     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10800     values[0] = 1.0;
10801     values[1] = 1.0;
10802     values[2] = 0.0;
10803     values[3] = 0.0;
10804     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10805     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10806     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10807     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10808     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10809     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10810     values[0] = -1.0;
10811     values[1] = 0.0;
10812     values[2] = 0.0;
10813     values[3] = 0.0;
10814     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10815     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10816     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10817     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10818     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10819     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10820     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10821     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10822     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10823     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10824
10825     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10826     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10827
10828     hr = IDirect3DDevice9_BeginScene(device);
10829     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10830     if(SUCCEEDED(hr))
10831     {
10832         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10833         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10834         hr = IDirect3DDevice9_EndScene(device);
10835         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10836     }
10837     color = getPixelColor(device, 320, 240);
10838     ok(color_match(color, 0x0000ff00, 1),
10839        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10840     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10841     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10842
10843     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10844     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10845     IDirect3DVertexShader9_Release(shader);
10846 }
10847
10848 static void sgn_test(IDirect3DDevice9 *device) {
10849     const DWORD shader_code[] = {
10850         0xfffe0200,                                                             /* vs_2_0                       */
10851         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10852         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10853         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10854         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10855         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10856         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10857         0x0000ffff                                                              /* end                          */
10858     };
10859     IDirect3DVertexShader9 *shader;
10860     HRESULT hr;
10861     DWORD color;
10862     const float quad[] = {
10863         -1.0,   -1.0,   0.1,
10864          1.0,   -1.0,   0.1,
10865         -1.0,    1.0,   0.1,
10866          1.0,    1.0,   0.1
10867     };
10868
10869     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10870     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10871     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10872     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10873     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10874     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10875     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10876     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10877
10878     hr = IDirect3DDevice9_BeginScene(device);
10879     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10880     if(SUCCEEDED(hr))
10881     {
10882         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10883         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10884         hr = IDirect3DDevice9_EndScene(device);
10885         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10886     }
10887     color = getPixelColor(device, 320, 240);
10888     ok(color_match(color, 0x008000ff, 1),
10889        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10890     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10891     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10892
10893     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10894     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10895     IDirect3DVertexShader9_Release(shader);
10896 }
10897
10898 static void viewport_test(IDirect3DDevice9 *device) {
10899     HRESULT hr;
10900     DWORD color;
10901     D3DVIEWPORT9 vp, old_vp;
10902     BOOL draw_failed = TRUE;
10903     const float quad[] =
10904     {
10905         -0.5,   -0.5,   0.1,
10906          0.5,   -0.5,   0.1,
10907         -0.5,    0.5,   0.1,
10908          0.5,    0.5,   0.1
10909     };
10910
10911     memset(&old_vp, 0, sizeof(old_vp));
10912     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10913     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10914
10915     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10916     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10917
10918     /* Test a viewport with Width and Height bigger than the surface dimensions
10919      *
10920      * TODO: Test Width < surface.width, but X + Width > surface.width
10921      * TODO: Test Width < surface.width, what happens with the height?
10922      *
10923      * The expected behavior is that the viewport behaves like the "default"
10924      * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
10925      * MinZ = 0.0, MaxZ = 1.0.
10926      *
10927      * Starting with Windows 7 the behavior among driver versions is not
10928      * consistent. The SetViewport call is accepted on all drivers. Some
10929      * drivers(older nvidia ones) refuse to draw and return an error. Newer
10930      * nvidia drivers draw, but use the actual values in the viewport and only
10931      * display the upper left part on the surface.
10932      */
10933     memset(&vp, 0, sizeof(vp));
10934     vp.X = 0;
10935     vp.Y = 0;
10936     vp.Width = 10000;
10937     vp.Height = 10000;
10938     vp.MinZ = 0.0;
10939     vp.MaxZ = 0.0;
10940     hr = IDirect3DDevice9_SetViewport(device, &vp);
10941     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10942
10943     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10944     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10945     hr = IDirect3DDevice9_BeginScene(device);
10946     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10947     if(SUCCEEDED(hr))
10948     {
10949         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10950         ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10951         draw_failed = FAILED(hr);
10952         hr = IDirect3DDevice9_EndScene(device);
10953         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10954     }
10955
10956     if(!draw_failed)
10957     {
10958         color = getPixelColor(device, 158, 118);
10959         ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10960         color = getPixelColor(device, 162, 118);
10961         ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10962         color = getPixelColor(device, 158, 122);
10963         ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10964         color = getPixelColor(device, 162, 122);
10965         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
10966
10967         color = getPixelColor(device, 478, 358);
10968         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
10969         color = getPixelColor(device, 482, 358);
10970         ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10971         color = getPixelColor(device, 478, 362);
10972         ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10973         color = getPixelColor(device, 482, 362);
10974         ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10975     }
10976
10977     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10978     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10979
10980     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10981     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10982 }
10983
10984 /* This test tests depth clamping / clipping behaviour:
10985  *   - With software vertex processing, depth values are clamped to the
10986  *     minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
10987  *     when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
10988  *     same as regular vertices here.
10989  *   - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
10990  *     Normal vertices are always clipped. Pretransformed vertices are
10991  *     clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
10992  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10993  */
10994 static void depth_clamp_test(IDirect3DDevice9 *device)
10995 {
10996     const struct tvertex quad1[] =
10997     {
10998         {  0.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
10999         {640.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
11000         {  0.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
11001         {640.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
11002     };
11003     const struct tvertex quad2[] =
11004     {
11005         {  0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
11006         {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
11007         {  0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
11008         {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
11009     };
11010     const struct tvertex quad3[] =
11011     {
11012         {112.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
11013         {208.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
11014         {112.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
11015         {208.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
11016     };
11017     const struct tvertex quad4[] =
11018     {
11019         { 42.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
11020         {112.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
11021         { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
11022         {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
11023     };
11024     const struct vertex quad5[] =
11025     {
11026         { -0.5f,   0.5f, 10.0f,       0xff14f914},
11027         {  0.5f,   0.5f, 10.0f,       0xff14f914},
11028         { -0.5f,  -0.5f, 10.0f,       0xff14f914},
11029         {  0.5f,  -0.5f, 10.0f,       0xff14f914},
11030     };
11031     const struct vertex quad6[] =
11032     {
11033         { -1.0f,   0.5f, 10.0f,      0xfff91414},
11034         {  1.0f,   0.5f, 10.0f,      0xfff91414},
11035         { -1.0f,  0.25f, 10.0f,      0xfff91414},
11036         {  1.0f,  0.25f, 10.0f,      0xfff91414},
11037     };
11038
11039     D3DVIEWPORT9 vp;
11040     D3DCOLOR color;
11041     D3DCAPS9 caps;
11042     HRESULT hr;
11043
11044     vp.X = 0;
11045     vp.Y = 0;
11046     vp.Width = 640;
11047     vp.Height = 480;
11048     vp.MinZ = 0.0;
11049     vp.MaxZ = 7.5;
11050
11051     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11052     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11053
11054     hr = IDirect3DDevice9_SetViewport(device, &vp);
11055     if(FAILED(hr))
11056     {
11057         /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
11058          * the tests because the 7.5 is just intended to show that it doesn't have
11059          * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
11060          * viewport and continue.
11061          */
11062         ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
11063         vp.MaxZ = 1.0;
11064         hr = IDirect3DDevice9_SetViewport(device, &vp);
11065     }
11066     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11067
11068     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
11069     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11070
11071     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
11072     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11073     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11074     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11075     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11076     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11077     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11078     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11079
11080     hr = IDirect3DDevice9_BeginScene(device);
11081     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11082
11083     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11084     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11085
11086     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11087     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11088     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11089     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11090
11091     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11092     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11093
11094     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11095     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11096     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
11097     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11098
11099     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
11100     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11101
11102     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11103     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11104
11105     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
11106     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11107
11108     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11109     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11110
11111     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
11112     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11113
11114     hr = IDirect3DDevice9_EndScene(device);
11115     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11116
11117     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
11118     {
11119         color = getPixelColor(device, 75, 75);
11120         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11121         color = getPixelColor(device, 150, 150);
11122         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11123         color = getPixelColor(device, 320, 240);
11124         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11125         color = getPixelColor(device, 320, 330);
11126         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11127         color = getPixelColor(device, 320, 330);
11128         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11129     }
11130     else
11131     {
11132         color = getPixelColor(device, 75, 75);
11133         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11134         color = getPixelColor(device, 150, 150);
11135         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11136         color = getPixelColor(device, 320, 240);
11137         ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11138         color = getPixelColor(device, 320, 330);
11139         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11140         color = getPixelColor(device, 320, 330);
11141         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11142     }
11143
11144     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11145     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11146
11147     vp.MinZ = 0.0;
11148     vp.MaxZ = 1.0;
11149     hr = IDirect3DDevice9_SetViewport(device, &vp);
11150     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11151 }
11152
11153 static void depth_bounds_test(IDirect3DDevice9 *device)
11154 {
11155     const struct tvertex quad1[] =
11156     {
11157         {    0,    0, 0.0f, 1, 0xfff9e814},
11158         {  640,    0, 0.0f, 1, 0xfff9e814},
11159         {    0,  480, 1.0f, 1, 0xfff9e814},
11160         {  640,  480, 1.0f, 1, 0xfff9e814},
11161     };
11162     const struct tvertex quad2[] =
11163     {
11164         {    0,    0,  0.6f, 1, 0xff002b7f},
11165         {  640,    0,  0.6f, 1, 0xff002b7f},
11166         {    0,  480,  0.6f, 1, 0xff002b7f},
11167         {  640,  480,  0.6f, 1, 0xff002b7f},
11168     };
11169     const struct tvertex quad3[] =
11170     {
11171         {    0,  100, 0.6f, 1, 0xfff91414},
11172         {  640,  100, 0.6f, 1, 0xfff91414},
11173         {    0,  160, 0.6f, 1, 0xfff91414},
11174         {  640,  160, 0.6f, 1, 0xfff91414},
11175     };
11176
11177     union {
11178         DWORD d;
11179         float f;
11180     } tmpvalue;
11181
11182     IDirect3D9 *d3d = NULL;
11183     IDirect3DSurface9 *offscreen_surface = NULL;
11184     D3DCOLOR color;
11185     HRESULT hr;
11186
11187     IDirect3DDevice9_GetDirect3D(device, &d3d);
11188     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11189             0,  D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
11190         skip("No NVDB (depth bounds test) support\n");
11191         IDirect3D9_Release(d3d);
11192         return;
11193     }
11194     IDirect3D9_Release(d3d);
11195
11196     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
11197             MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
11198     ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
11199     if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
11200
11201     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
11202     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11203
11204     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11205     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11206     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
11207     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11208     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11209     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11210     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11211     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11212
11213
11214     hr = IDirect3DDevice9_BeginScene(device);
11215     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11216
11217     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11218     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11219
11220     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11221     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11222
11223     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
11224     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11225
11226     tmpvalue.f = 0.625;
11227     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11228     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11229
11230     tmpvalue.f = 0.75;
11231     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
11232     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11233
11234     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11235     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11236
11237     tmpvalue.f = 0.75;
11238     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11239     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11240
11241     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11242     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11243
11244     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
11245     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11246
11247     hr = IDirect3DDevice9_EndScene(device);
11248     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11249
11250     color = getPixelColor(device, 150, 130);
11251     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11252     color = getPixelColor(device, 150, 200);
11253     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11254     color = getPixelColor(device, 150, 300-5);
11255     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11256     color = getPixelColor(device, 150, 300+5);
11257     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11258     color = getPixelColor(device, 150, 330);
11259     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11260     color = getPixelColor(device, 150, 360-5);
11261     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11262     color = getPixelColor(device, 150, 360+5);
11263     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11264
11265     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11266     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11267 }
11268
11269 static void depth_buffer_test(IDirect3DDevice9 *device)
11270 {
11271     static const struct vertex quad1[] =
11272     {
11273         { -1.0,  1.0, 0.33f, 0xff00ff00},
11274         {  1.0,  1.0, 0.33f, 0xff00ff00},
11275         { -1.0, -1.0, 0.33f, 0xff00ff00},
11276         {  1.0, -1.0, 0.33f, 0xff00ff00},
11277     };
11278     static const struct vertex quad2[] =
11279     {
11280         { -1.0,  1.0, 0.50f, 0xffff00ff},
11281         {  1.0,  1.0, 0.50f, 0xffff00ff},
11282         { -1.0, -1.0, 0.50f, 0xffff00ff},
11283         {  1.0, -1.0, 0.50f, 0xffff00ff},
11284     };
11285     static const struct vertex quad3[] =
11286     {
11287         { -1.0,  1.0, 0.66f, 0xffff0000},
11288         {  1.0,  1.0, 0.66f, 0xffff0000},
11289         { -1.0, -1.0, 0.66f, 0xffff0000},
11290         {  1.0, -1.0, 0.66f, 0xffff0000},
11291     };
11292     static const DWORD expected_colors[4][4] =
11293     {
11294         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11295         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11296         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11297         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11298     };
11299
11300     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
11301     unsigned int i, j;
11302     D3DVIEWPORT9 vp;
11303     D3DCOLOR color;
11304     HRESULT hr;
11305
11306     vp.X = 0;
11307     vp.Y = 0;
11308     vp.Width = 640;
11309     vp.Height = 480;
11310     vp.MinZ = 0.0;
11311     vp.MaxZ = 1.0;
11312
11313     hr = IDirect3DDevice9_SetViewport(device, &vp);
11314     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11315
11316     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11317     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11318     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11319     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11320     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11321     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11322     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11323     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11324     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11325     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11326
11327     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11328     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11329     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
11330             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11331     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11332     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11333             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11334     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11335     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11336             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
11337     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11338
11339     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11340     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11341     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11342     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11343
11344     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11345     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11346     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11347     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11348
11349     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11350     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11351     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11352     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11353
11354     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11355     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11356     hr = IDirect3DDevice9_BeginScene(device);
11357     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11358     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11359     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11360     hr = IDirect3DDevice9_EndScene(device);
11361     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11362
11363     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11364     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11365     IDirect3DSurface9_Release(backbuffer);
11366     IDirect3DSurface9_Release(rt3);
11367     IDirect3DSurface9_Release(rt2);
11368     IDirect3DSurface9_Release(rt1);
11369
11370     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11371     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11372
11373     hr = IDirect3DDevice9_BeginScene(device);
11374     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11375     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11376     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11377     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11378     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11379     hr = IDirect3DDevice9_EndScene(device);
11380     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11381
11382     for (i = 0; i < 4; ++i)
11383     {
11384         for (j = 0; j < 4; ++j)
11385         {
11386             unsigned int x = 80 * ((2 * j) + 1);
11387             unsigned int y = 60 * ((2 * i) + 1);
11388             color = getPixelColor(device, x, y);
11389             ok(color_match(color, expected_colors[i][j], 0),
11390                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11391         }
11392     }
11393
11394     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11395     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11396 }
11397
11398 /* Test that partial depth copies work the way they're supposed to. The clear
11399  * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
11400  * the following draw should only copy back the part that was modified. */
11401 static void depth_buffer2_test(IDirect3DDevice9 *device)
11402 {
11403     static const struct vertex quad[] =
11404     {
11405         { -1.0,  1.0, 0.66f, 0xffff0000},
11406         {  1.0,  1.0, 0.66f, 0xffff0000},
11407         { -1.0, -1.0, 0.66f, 0xffff0000},
11408         {  1.0, -1.0, 0.66f, 0xffff0000},
11409     };
11410
11411     IDirect3DSurface9 *backbuffer, *rt1, *rt2;
11412     unsigned int i, j;
11413     D3DVIEWPORT9 vp;
11414     D3DCOLOR color;
11415     HRESULT hr;
11416
11417     vp.X = 0;
11418     vp.Y = 0;
11419     vp.Width = 640;
11420     vp.Height = 480;
11421     vp.MinZ = 0.0;
11422     vp.MaxZ = 1.0;
11423
11424     hr = IDirect3DDevice9_SetViewport(device, &vp);
11425     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11426
11427     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11428     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11429     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11430     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11431     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11432     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11433     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11434     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11435     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11436     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11437
11438     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11439             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11440     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11441     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11442             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11443     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11444     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11445     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11446
11447     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11448     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11449     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11450     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11451
11452     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11453     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11454     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
11455     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11456
11457     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11458     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11459     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11460     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11461
11462     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11463     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11464     IDirect3DSurface9_Release(backbuffer);
11465     IDirect3DSurface9_Release(rt2);
11466     IDirect3DSurface9_Release(rt1);
11467
11468     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11469     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11470
11471     hr = IDirect3DDevice9_BeginScene(device);
11472     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11473     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11474     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11475     hr = IDirect3DDevice9_EndScene(device);
11476     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11477
11478     for (i = 0; i < 4; ++i)
11479     {
11480         for (j = 0; j < 4; ++j)
11481         {
11482             unsigned int x = 80 * ((2 * j) + 1);
11483             unsigned int y = 60 * ((2 * i) + 1);
11484             color = getPixelColor(device, x, y);
11485             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11486                     "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
11487         }
11488     }
11489
11490     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11491     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11492 }
11493
11494 static void depth_blit_test(IDirect3DDevice9 *device)
11495 {
11496     static const struct vertex quad1[] =
11497     {
11498         { -1.0,  1.0, 0.50f, 0xff00ff00},
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     };
11503     static const struct vertex quad2[] =
11504     {
11505         { -1.0,  1.0, 0.66f, 0xff0000ff},
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     };
11510     static const DWORD expected_colors[4][4] =
11511     {
11512         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11513         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11514         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11515         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11516     };
11517
11518     IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
11519     RECT src_rect, dst_rect;
11520     unsigned int i, j;
11521     D3DVIEWPORT9 vp;
11522     D3DCOLOR color;
11523     HRESULT hr;
11524
11525     vp.X = 0;
11526     vp.Y = 0;
11527     vp.Width = 640;
11528     vp.Height = 480;
11529     vp.MinZ = 0.0;
11530     vp.MaxZ = 1.0;
11531
11532     hr = IDirect3DDevice9_SetViewport(device, &vp);
11533     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11534
11535     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11536     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11537     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11538     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11539     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11540     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11541     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11542     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11543     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
11544     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11545
11546     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11547     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11548     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11549     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11550     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11551     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11552     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11553     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11554
11555     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11556     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11557     SetRect(&dst_rect, 0, 0, 480, 360);
11558     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11559     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11560     SetRect(&dst_rect, 0, 0, 320, 240);
11561     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11562     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11563
11564     /* Partial blit. */
11565     SetRect(&src_rect, 0, 0, 320, 240);
11566     SetRect(&dst_rect, 0, 0, 320, 240);
11567     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11568     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11569     /* Flipped. */
11570     SetRect(&src_rect, 0, 0, 640, 480);
11571     SetRect(&dst_rect, 0, 480, 640, 0);
11572     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11573     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11574     /* Full, explicit. */
11575     SetRect(&src_rect, 0, 0, 640, 480);
11576     SetRect(&dst_rect, 0, 0, 640, 480);
11577     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11578     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11579     /* Filtered blit. */
11580     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11581     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11582     /* Depth -> color blit.*/
11583     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11584     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11585     IDirect3DSurface9_Release(backbuffer);
11586     /* Full surface, different sizes */
11587     hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
11588     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11589     hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
11590     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11591
11592     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11593     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11594     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11595     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11596     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11597     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11598     IDirect3DSurface9_Release(ds3);
11599     IDirect3DSurface9_Release(ds2);
11600     IDirect3DSurface9_Release(ds1);
11601
11602     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11603     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11604     hr = IDirect3DDevice9_BeginScene(device);
11605     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11606     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11607     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11608     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11609     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11610     hr = IDirect3DDevice9_EndScene(device);
11611     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11612
11613     for (i = 0; i < 4; ++i)
11614     {
11615         for (j = 0; j < 4; ++j)
11616         {
11617             unsigned int x = 80 * ((2 * j) + 1);
11618             unsigned int y = 60 * ((2 * i) + 1);
11619             color = getPixelColor(device, x, y);
11620             ok(color_match(color, expected_colors[i][j], 0),
11621                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11622         }
11623     }
11624
11625     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11626     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11627 }
11628
11629 static void intz_test(IDirect3DDevice9 *device)
11630 {
11631     static const DWORD ps_code[] =
11632     {
11633         0xffff0200,                                                             /* ps_2_0                       */
11634         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11635         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11636         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11637         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11638         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11639         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11640         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11641         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11642         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
11643         0x0000ffff,                                                             /* end                          */
11644     };
11645     struct
11646     {
11647         float x, y, z;
11648         float s, t, p, q;
11649     }
11650     quad[] =
11651     {
11652         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11653         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11654         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11655         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11656     },
11657     half_quad_1[] =
11658     {
11659         { -1.0f,  0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11660         {  1.0f,  0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11661         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11662         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11663     },
11664     half_quad_2[] =
11665     {
11666         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11667         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11668         { -1.0f,  0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11669         {  1.0f,  0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11670     };
11671     struct
11672     {
11673         UINT x, y;
11674         D3DCOLOR color;
11675     }
11676     expected_colors[] =
11677     {
11678         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11679         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11680         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11681         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11682         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11683         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11684         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11685         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11686     };
11687
11688     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11689     IDirect3DTexture9 *texture;
11690     IDirect3DPixelShader9 *ps;
11691     IDirect3DSurface9 *ds;
11692     IDirect3D9 *d3d9;
11693     D3DCAPS9 caps;
11694     HRESULT hr;
11695     UINT i;
11696
11697     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11698     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11699     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11700     {
11701         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11702         return;
11703     }
11704     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
11705     {
11706         skip("No unconditional NP2 texture support, skipping INTZ test.\n");
11707         return;
11708     }
11709
11710     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11711     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11712
11713     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11714             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11715     if (FAILED(hr))
11716     {
11717         skip("No INTZ support, skipping INTZ test.\n");
11718         return;
11719     }
11720
11721     IDirect3D9_Release(d3d9);
11722
11723     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11724     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11725     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11726     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11727
11728     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11729             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11730     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11731     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11732             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11733     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11734     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11735     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11736
11737     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11738     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11739     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11740     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11741     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11742     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11743     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11744     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11745     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11746     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11747
11748     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11749     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11750     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11751     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11752     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11753     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11754     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11755     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11756     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11757     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11758
11759     /* Render offscreen, using the INTZ texture as depth buffer */
11760     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11761     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11762     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11763     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11764     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11765     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11766     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11767     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11768
11769     /* Setup the depth/stencil surface. */
11770     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11771     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11772
11773     hr = IDirect3DDevice9_BeginScene(device);
11774     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11775     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11776     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11777     hr = IDirect3DDevice9_EndScene(device);
11778     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11779
11780     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11781     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11782     IDirect3DSurface9_Release(ds);
11783     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11784     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11785     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11786     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11787     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11788     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11789
11790     /* Read the depth values back. */
11791     hr = IDirect3DDevice9_BeginScene(device);
11792     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11793     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11794     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11795     hr = IDirect3DDevice9_EndScene(device);
11796     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11797
11798     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11799     {
11800         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11801         ok(color_match(color, expected_colors[i].color, 1),
11802                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11803                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11804     }
11805
11806     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11807     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11808
11809     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11810     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11811     IDirect3DTexture9_Release(texture);
11812
11813     /* Render onscreen while using the INTZ texture as depth buffer */
11814     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11815             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11816     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11817     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11818     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11819     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11820     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11821     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11822
11823     /* Setup the depth/stencil surface. */
11824     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11825     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11826
11827     hr = IDirect3DDevice9_BeginScene(device);
11828     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11829     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11830     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11831     hr = IDirect3DDevice9_EndScene(device);
11832     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11833
11834     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11835     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11836     IDirect3DSurface9_Release(ds);
11837     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11838     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11839     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11840     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11841
11842     /* Read the depth values back. */
11843     hr = IDirect3DDevice9_BeginScene(device);
11844     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11845     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11846     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11847     hr = IDirect3DDevice9_EndScene(device);
11848     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11849
11850     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11851     {
11852         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11853         ok(color_match(color, expected_colors[i].color, 1),
11854                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11855                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11856     }
11857
11858     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11859     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11860
11861     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11862     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11863     IDirect3DTexture9_Release(texture);
11864
11865     /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
11866     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11867             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11868     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11869     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11870
11871     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11872     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11873     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11874     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11875     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11876     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11877
11878     /* Setup the depth/stencil surface. */
11879     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11880     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11881
11882     hr = IDirect3DDevice9_BeginScene(device);
11883     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11884     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
11885     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11886     hr = IDirect3DDevice9_EndScene(device);
11887     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11888
11889     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11890     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11891
11892     hr = IDirect3DDevice9_BeginScene(device);
11893     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11894     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
11895     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11896     hr = IDirect3DDevice9_EndScene(device);
11897     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11898
11899     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11900     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11901     IDirect3DSurface9_Release(ds);
11902     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11903     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11904     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11905     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11906
11907     /* Read the depth values back. */
11908     hr = IDirect3DDevice9_BeginScene(device);
11909     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11910     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11911     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11912     hr = IDirect3DDevice9_EndScene(device);
11913     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11914
11915     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11916     {
11917         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11918         ok(color_match(color, expected_colors[i].color, 1),
11919                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11920                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11921     }
11922
11923     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11924     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11925
11926     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11927     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11928     IDirect3DSurface9_Release(original_ds);
11929     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11930     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11931     IDirect3DTexture9_Release(texture);
11932     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11933     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11934     IDirect3DPixelShader9_Release(ps);
11935
11936     IDirect3DSurface9_Release(original_rt);
11937     IDirect3DSurface9_Release(rt);
11938 }
11939
11940 static void shadow_test(IDirect3DDevice9 *device)
11941 {
11942     static const DWORD ps_code[] =
11943     {
11944         0xffff0200,                                                             /* ps_2_0                       */
11945         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11946         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11947         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11948         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11949         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11950         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11951         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11952         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11953         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11954         0x0000ffff,                                                             /* end                          */
11955     };
11956     struct
11957     {
11958         D3DFORMAT format;
11959         const char *name;
11960     }
11961     formats[] =
11962     {
11963         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
11964         {D3DFMT_D32,            "D3DFMT_D32"},
11965         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
11966         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
11967         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
11968         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
11969         {D3DFMT_D16,            "D3DFMT_D16"},
11970         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
11971         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
11972     };
11973     struct
11974     {
11975         float x, y, z;
11976         float s, t, p, q;
11977     }
11978     quad[] =
11979     {
11980         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11981         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11982         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11983         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11984     };
11985     struct
11986     {
11987         UINT x, y;
11988         D3DCOLOR color;
11989     }
11990     expected_colors[] =
11991     {
11992         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11993         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11994         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11995         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11996         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11997         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11998         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11999         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12000     };
12001
12002     IDirect3DSurface9 *original_ds, *original_rt, *rt;
12003     IDirect3DPixelShader9 *ps;
12004     IDirect3D9 *d3d9;
12005     D3DCAPS9 caps;
12006     HRESULT hr;
12007     UINT i;
12008
12009     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12010     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12011     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
12012     {
12013         skip("No pixel shader 2.0 support, skipping shadow test.\n");
12014         return;
12015     }
12016
12017     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
12018     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12019     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12020     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12021     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
12022     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
12023
12024     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
12025             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12026     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12027     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12028     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12029
12030     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
12031     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12032     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12033     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12034     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
12035     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12036     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12037     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12038     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12039     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12040
12041     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
12042     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12043     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
12044     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12045     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
12046     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12047     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
12048     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12049     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12050     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12051
12052     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
12053     {
12054         D3DFORMAT format = formats[i].format;
12055         IDirect3DTexture9 *texture;
12056         IDirect3DSurface9 *ds;
12057         unsigned int j;
12058
12059         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12060                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
12061         if (FAILED(hr)) continue;
12062
12063         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
12064                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
12065         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12066
12067         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
12068         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12069
12070         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12071         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12072
12073         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12074         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12075
12076         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12077         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12078
12079         /* Setup the depth/stencil surface. */
12080         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
12081         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12082
12083         hr = IDirect3DDevice9_BeginScene(device);
12084         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12085         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12086         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12087         hr = IDirect3DDevice9_EndScene(device);
12088         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12089
12090         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
12091         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12092         IDirect3DSurface9_Release(ds);
12093
12094         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12095         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12096
12097         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12098         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12099
12100         hr = IDirect3DDevice9_SetPixelShader(device, ps);
12101         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12102
12103         /* Do the actual shadow mapping. */
12104         hr = IDirect3DDevice9_BeginScene(device);
12105         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12106         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12107         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12108         hr = IDirect3DDevice9_EndScene(device);
12109         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12110
12111         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12112         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12113         IDirect3DTexture9_Release(texture);
12114
12115         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
12116         {
12117             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
12118             ok(color_match(color, expected_colors[j].color, 0),
12119                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
12120                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
12121                     formats[i].name, color);
12122         }
12123
12124         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12125         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12126     }
12127
12128     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12129     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12130     IDirect3DPixelShader9_Release(ps);
12131
12132     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
12133     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12134     IDirect3DSurface9_Release(original_ds);
12135
12136     IDirect3DSurface9_Release(original_rt);
12137     IDirect3DSurface9_Release(rt);
12138
12139     IDirect3D9_Release(d3d9);
12140 }
12141
12142 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
12143 {
12144     const struct vertex quad1[] =
12145     {
12146         {-1.0f, -1.0f, 0.0f, 0xfff9e814},
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     };
12151     const struct vertex quad2[] =
12152     {
12153         {-1.0f, -1.0f, 0.0f, 0xff002b7f},
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     };
12158     D3DCOLOR color;
12159     HRESULT hr;
12160
12161     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
12162     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12163
12164     hr = IDirect3DDevice9_BeginScene(device);
12165     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12166
12167     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12168     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12169
12170     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12171     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12172     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12173     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12174
12175     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
12176     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12177     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12178     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12179
12180     hr = IDirect3DDevice9_EndScene(device);
12181     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12182
12183     color = getPixelColor(device, 1, 240);
12184     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12185     color = getPixelColor(device, 638, 240);
12186     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12187
12188     color = getPixelColor(device, 1, 241);
12189     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12190     color = getPixelColor(device, 638, 241);
12191     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12192 }
12193
12194 static void clip_planes_test(IDirect3DDevice9 *device)
12195 {
12196     const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
12197
12198     const DWORD shader_code[] = {
12199         0xfffe0200, /* vs_2_0 */
12200         0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12201         0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
12202         0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12203         0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
12204         0x0000ffff /* end */
12205     };
12206     IDirect3DVertexShader9 *shader;
12207
12208     IDirect3DTexture9 *offscreen = NULL;
12209     IDirect3DSurface9 *offscreen_surface, *original_rt;
12210     HRESULT hr;
12211
12212     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12213     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12214
12215     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12216     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12217     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12218     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12219     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12220     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12221     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
12222     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12223
12224     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12225     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12226     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12227     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
12228
12229     IDirect3DDevice9_SetClipPlane(device, 0, plane0);
12230
12231     clip_planes(device, "Onscreen FFP");
12232
12233     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
12234     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12235     hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
12236     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12237     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12238     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12239
12240     clip_planes(device, "Offscreen FFP");
12241
12242     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12243     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12244
12245     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12246     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
12247     hr = IDirect3DDevice9_SetVertexShader(device, shader);
12248     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
12249
12250     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12251     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12252
12253     clip_planes(device, "Onscreen vertex shader");
12254
12255     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12256     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12257
12258     clip_planes(device, "Offscreen vertex shader");
12259
12260     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12261     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12262
12263     IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12264     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12265     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12266     IDirect3DVertexShader9_Release(shader);
12267     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12268     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12269     IDirect3DSurface9_Release(original_rt);
12270     IDirect3DSurface9_Release(offscreen_surface);
12271     IDirect3DTexture9_Release(offscreen);
12272 }
12273
12274 static void fp_special_test(IDirect3DDevice9 *device)
12275 {
12276     static const DWORD vs_header[] =
12277     {
12278         0xfffe0200,                                                             /* vs_2_0                       */
12279         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
12280         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
12281         0x0200001f, 0x80000005, 0x900f0001,                                     /* dcl_texcoord0 v1             */
12282     };
12283
12284     static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001};         /* log r0.x, v1.x               */
12285     static const DWORD vs_pow[] =
12286             {0x03000020, 0x80010000, 0x90000001, 0x90000001};                   /* pow r0.x, v1.x, v1.x         */
12287     static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001};         /* nrm r0.xyz, v1.x             */
12288     static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001};        /* rcp r0.x, v1.x               */
12289     static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001};        /* rcp r0.x, -v1.x              */
12290     static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001};        /* rsq r0.x, v1.x               */
12291     static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001};        /* rsq r0.x, -v1.x              */
12292     static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001,          /* lit r0, v1.xxxx              */
12293             0x02000001, 0x80010000, 0x80aa0000};                                /* mov r0.x, v0.z               */
12294
12295     static const DWORD vs_footer[] =
12296     {
12297         0x03000005, 0x80020000, 0x80000000, 0xa0ff0000,                         /* mul r0.y, r0.x, c0.w         */
12298         0x0300000d, 0x80040000, 0x80000000, 0x80550000,                         /* sge r0.z, r0.x, r0.y         */
12299         0x0300000d, 0x80020000, 0x80e40000, 0x80000000,                         /* sge r0.y, r0, r0.x           */
12300         0x03000005, 0x80040000, 0x80550000, 0x80e40000,                         /* mul r0.z, r0.y, r0           */
12301         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
12302         0x0300000c, 0x80020000, 0x80000000, 0x80000000,                         /* slt r0.y, r0.x, r0.x         */
12303         0x03000002, 0x80040000, 0x80550000, 0x80550000,                         /* add r0.z, r0.y, r0.y         */
12304         0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000,                         /* slt r0.y, c0.x, r0.w         */
12305         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
12306         0x03000002, 0x80040000, 0x81550000, 0xa0e40000,                         /* add r0.z, -r0.y, c0          */
12307         0x0300000c, 0x80080000, 0xa0000000, 0x80e40000,                         /* slt r0.w, c0.x, r0           */
12308         0x03000005, 0x80040000, 0x80ff0000, 0x80e40000,                         /* mul r0.z, r0.w, r0           */
12309         0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000,             /* mad r0.y, r0.z, c0, r0       */
12310         0x02000001, 0xe0030000, 0x80e40000,                                     /* mov oT0.xy, r0               */
12311         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
12312         0x0000ffff,                                                             /* end                          */
12313     };
12314
12315     static const struct
12316     {
12317         const char *name;
12318         const DWORD *ops;
12319         DWORD size;
12320         D3DCOLOR r600;
12321         D3DCOLOR nv40;
12322         D3DCOLOR nv50;
12323     }
12324     vs_body[] =
12325     {
12326         /* The basic ideas here are:
12327          *     2.0 * +/-INF == +/-INF
12328          *     NAN != NAN
12329          *
12330          * The vertex shader value is written to the red component, with 0.0
12331          * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
12332          * result in 0x00. The pixel shader value is written to the green
12333          * component, but here 0.0 also results in 0x00. The actual value is
12334          * written to the blue component.
12335          *
12336          * There are considerable differences between graphics cards in how
12337          * these are handled, but pow and nrm never generate INF or NAN. */
12338         {"log",     vs_log,     sizeof(vs_log),     0x00000000, 0x00ff0000, 0x00ff7f00},
12339         {"pow",     vs_pow,     sizeof(vs_pow),     0x000000ff, 0x0000ff00, 0x000000ff},
12340         {"nrm",     vs_nrm,     sizeof(vs_nrm),     0x00ff0000, 0x0000ff00, 0x00ff0000},
12341         {"rcp1",    vs_rcp1,    sizeof(vs_rcp1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12342         {"rcp2",    vs_rcp2,    sizeof(vs_rcp2),    0x00000000, 0x00ff0000, 0x00ff7f00},
12343         {"rsq1",    vs_rsq1,    sizeof(vs_rsq1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12344         {"rsq2",    vs_rsq2,    sizeof(vs_rsq2),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12345         {"lit",     vs_lit,     sizeof(vs_lit),     0x00ff0000, 0x00ff0000, 0x00ff0000},
12346     };
12347
12348     static const DWORD ps_code[] =
12349     {
12350         0xffff0200,                                                             /* ps_2_0                       */
12351         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
12352         0x0200001f, 0x80000000, 0xb0030000,                                     /* dcl t0.xy                    */
12353         0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000,                         /* max r1.x, t0, c0             */
12354         0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000,                         /* min r0.x, t0, c0             */
12355         0x03000002, 0x80010000, 0x80e40000, 0x81e40001,                         /* add r0.x, r0, -r1            */
12356         0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000,             /* mad r1.x, t0, c0.w. -t0      */
12357         0x02000023, 0x80010002, 0x80e40001,                                     /* abs r2.x, r1                 */
12358         0x02000023, 0x80010000, 0x80e40000,                                     /* abs r0.x, r0                 */
12359         0x02000023, 0x80010001, 0xb0e40000,                                     /* abs r1.x, t0                 */
12360         0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r2, c0.z, c0      */
12361         0x02000023, 0x80010002, 0x80e40002,                                     /* abs r2.x, r2                 */
12362         0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r1.x, -r1, c0.z, c0      */
12363         0x02000023, 0x80010001, 0x80e40001,                                     /* abs r1.x, r1                 */
12364         0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r3.x, -r2, c0.z, c0      */
12365         0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r1, c0.z, c0      */
12366         0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000,             /* cmp r0.x, -r0, c0.y, c0      */
12367         0x03000005, 0x80010002, 0x80e40002, 0x80e40003,                         /* mul r2.x, r2, r3             */
12368         0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000,             /* cmp r0.x, -r2, c0.z, r0      */
12369         0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000,             /* cmp r0.y, -r1.x, r0.x, c0.x  */
12370         0x02000001, 0x80050000, 0xb0c90000,                                     /* mov r0.xz, t0.yzxw           */
12371         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.w, c0.z               */
12372         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
12373         0x0000ffff,                                                             /* end                          */
12374     };
12375
12376     struct
12377     {
12378         float x, y, z;
12379         float s;
12380     }
12381     quad[] =
12382     {
12383         { -1.0f,  1.0f, 0.0f, 0.0f},
12384         {  1.0f,  1.0f, 1.0f, 0.0f},
12385         { -1.0f, -1.0f, 0.0f, 0.0f},
12386         {  1.0f, -1.0f, 1.0f, 0.0f},
12387     };
12388
12389     IDirect3DPixelShader9 *ps;
12390     UINT body_size = 0;
12391     DWORD *vs_code;
12392     D3DCAPS9 caps;
12393     HRESULT hr;
12394     UINT i;
12395
12396     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12397     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12398     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12399     {
12400         skip("No shader model 2.0 support, skipping floating point specials test.\n");
12401         return;
12402     }
12403
12404     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
12405     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12406
12407     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12408     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12409     hr = IDirect3DDevice9_SetPixelShader(device, ps);
12410     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12411
12412     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12413     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12414
12415     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
12416     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12417
12418     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12419     {
12420         if (vs_body[i].size > body_size) body_size = vs_body[i].size;
12421     }
12422
12423     vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
12424     memcpy(vs_code, vs_header, sizeof(vs_header));
12425
12426     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12427     {
12428         DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
12429         IDirect3DVertexShader9 *vs;
12430         D3DCOLOR color;
12431
12432         memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
12433         offset += vs_body[i].size / sizeof(*vs_body[i].ops);
12434         memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
12435
12436         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
12437         ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
12438         hr = IDirect3DDevice9_SetVertexShader(device, vs);
12439         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12440
12441         hr = IDirect3DDevice9_BeginScene(device);
12442         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12443         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12444         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12445         hr = IDirect3DDevice9_EndScene(device);
12446         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12447
12448         color = getPixelColor(device, 320, 240);
12449         ok(color_match(color, vs_body[i].r600, 1)
12450                 || color_match(color, vs_body[i].nv40, 1)
12451                 || color_match(color, vs_body[i].nv50, 1),
12452                 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
12453                 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
12454
12455         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12456         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12457
12458         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12459         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12460         IDirect3DVertexShader9_Release(vs);
12461     }
12462
12463     HeapFree(GetProcessHeap(), 0, vs_code);
12464
12465     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12466     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12467     IDirect3DPixelShader9_Release(ps);
12468 }
12469
12470 static void srgbwrite_format_test(IDirect3DDevice9 *device)
12471 {
12472     IDirect3D9 *d3d;
12473     IDirect3DSurface9 *rt, *backbuffer;
12474     IDirect3DTexture9 *texture;
12475     HRESULT hr;
12476     int i;
12477     DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
12478     static const struct
12479     {
12480         D3DFORMAT fmt;
12481         const char *name;
12482     }
12483     formats[] =
12484     {
12485         { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
12486         { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
12487         { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
12488         { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
12489         { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
12490     };
12491     static const struct
12492     {
12493         float x, y, z;
12494         float u, v;
12495     }
12496     quad[] =
12497     {
12498         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12499         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12500         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12501         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12502     };
12503
12504     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12505     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12506     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12507     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12508     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
12509     ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
12510     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12511     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12512     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12513     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12514
12515     for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
12516     {
12517         if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12518                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
12519         {
12520             skip("Format %s not supported as render target, skipping test.\n",
12521                     formats[i].name);
12522             continue;
12523         }
12524
12525         hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
12526                                             D3DPOOL_DEFAULT, &texture, NULL);
12527         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12528         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
12529         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12530
12531         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
12532         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12533         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12534         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12535         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
12536         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12537
12538         hr = IDirect3DDevice9_BeginScene(device);
12539         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12540         if(SUCCEEDED(hr))
12541         {
12542             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
12543             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12544             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
12545             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12546             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12547             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12548
12549             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
12550             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12551             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12552             ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12553             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
12554             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12555             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12556             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12557             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12558             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12559             hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12560             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12561
12562             hr = IDirect3DDevice9_EndScene(device);
12563             ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12564         }
12565
12566         IDirect3DSurface9_Release(rt);
12567         IDirect3DTexture9_Release(texture);
12568
12569         color = getPixelColor(device, 360, 240);
12570         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12571                                     D3DUSAGE_QUERY_SRGBWRITE,
12572                                     D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
12573         {
12574             /* Big slop for R5G6B5 */
12575             ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
12576                 formats[i].name, color_srgb, color);
12577         }
12578         else
12579         {
12580             /* Big slop for R5G6B5 */
12581             ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
12582                 formats[i].name, color_rgb, color);
12583         }
12584
12585         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12586         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12587     }
12588
12589     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12590     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12591
12592     IDirect3D9_Release(d3d);
12593     IDirect3DSurface9_Release(backbuffer);
12594 }
12595
12596 static void ds_size_test(IDirect3DDevice9 *device)
12597 {
12598     IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
12599     HRESULT hr;
12600     DWORD num_passes;
12601     struct
12602     {
12603         float x, y, z;
12604     }
12605     quad[] =
12606     {
12607         {-1.0,  -1.0,   0.0 },
12608         {-1.0,   1.0,   0.0 },
12609         { 1.0,  -1.0,   0.0 },
12610         { 1.0,   1.0,   0.0 }
12611     };
12612
12613     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12614     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12615     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
12616     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
12617     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
12618     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
12619
12620     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12621     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12622     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
12623     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12624     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12625     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12626     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12627     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12628     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12629     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12630     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
12631     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
12632     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12633     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12634     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12635     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12636     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12637     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12638
12639     /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
12640      * but does not change the surface's contents. */
12641     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
12642     ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
12643     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
12644     ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
12645     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
12646     ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12647
12648     /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
12649
12650     /* Turning on any depth-related state results in a ValidateDevice failure */
12651     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12652     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12653     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12654     ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12655         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12656     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12657     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12658     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12659     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12660     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12661     ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12662         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12663
12664     /* Try to draw with the device in an invalid state */
12665     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12666     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12667     hr = IDirect3DDevice9_BeginScene(device);
12668     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12669     if(SUCCEEDED(hr))
12670     {
12671         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12672         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12673         hr = IDirect3DDevice9_EndScene(device);
12674         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12675
12676         /* Don't check the resulting draw unless we find an app that needs it. On nvidia ValidateDevice
12677          * returns CONFLICTINGRENDERSTATE, so the result is undefined. On AMD d3d seems to assume the
12678          * stored Z buffer value is 0.0 for all pixels, even those that are covered by the depth buffer */
12679     }
12680
12681     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12682     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12683     hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12684     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12685     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12686     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12687
12688     IDirect3DSurface9_Release(readback);
12689     IDirect3DSurface9_Release(ds);
12690     IDirect3DSurface9_Release(rt);
12691     IDirect3DSurface9_Release(old_rt);
12692     IDirect3DSurface9_Release(old_ds);
12693 }
12694
12695 static void unbound_sampler_test(IDirect3DDevice9 *device)
12696 {
12697     HRESULT hr;
12698     IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
12699     IDirect3DSurface9 *rt, *old_rt;
12700     DWORD color;
12701
12702     static const DWORD ps_code[] =
12703     {
12704         0xffff0200,                                     /* ps_2_0           */
12705         0x0200001f, 0x90000000, 0xa00f0800,             /* dcl_2d s0        */
12706         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12707         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12708         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12709         0x0000ffff,                                     /* end              */
12710     };
12711     static const DWORD ps_code_cube[] =
12712     {
12713         0xffff0200,                                     /* ps_2_0           */
12714         0x0200001f, 0x98000000, 0xa00f0800,             /* dcl_cube s0      */
12715         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12716         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12717         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12718         0x0000ffff,                                     /* end              */
12719     };
12720     static const DWORD ps_code_volume[] =
12721     {
12722         0xffff0200,                                     /* ps_2_0           */
12723         0x0200001f, 0xa0000000, 0xa00f0800,             /* dcl_volume s0    */
12724         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12725         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12726         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12727         0x0000ffff,                                     /* end              */
12728     };
12729
12730     static const struct
12731     {
12732         float x, y, z;
12733         float u, v;
12734     }
12735     quad[] =
12736     {
12737         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12738         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12739         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12740         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12741     };
12742
12743     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12744     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
12745
12746     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12747     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12748     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
12749     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12750     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
12751     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12752
12753     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
12754     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12755
12756     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12757     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12758
12759     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12760     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12761
12762     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
12763     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12764
12765     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
12766     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
12767
12768     hr = IDirect3DDevice9_SetPixelShader(device, ps);
12769     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12770
12771     hr = IDirect3DDevice9_BeginScene(device);
12772     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12773     if(SUCCEEDED(hr))
12774     {
12775         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12776         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12777
12778         hr = IDirect3DDevice9_EndScene(device);
12779         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12780     }
12781
12782     color = getPixelColorFromSurface(rt, 32, 32);
12783     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12784
12785     /* Now try with a cube texture */
12786     hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
12787     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12788
12789     hr = IDirect3DDevice9_BeginScene(device);
12790     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12791     if (SUCCEEDED(hr))
12792     {
12793         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12794         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12795
12796         hr = IDirect3DDevice9_EndScene(device);
12797         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12798     }
12799
12800     color = getPixelColorFromSurface(rt, 32, 32);
12801     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12802
12803     /* And then with a volume texture */
12804     hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
12805     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12806
12807     hr = IDirect3DDevice9_BeginScene(device);
12808     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12809     if (SUCCEEDED(hr))
12810     {
12811         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12812         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12813
12814         hr = IDirect3DDevice9_EndScene(device);
12815         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12816     }
12817
12818     color = getPixelColorFromSurface(rt, 32, 32);
12819     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12820
12821     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12822     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12823
12824     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12825     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12826
12827     IDirect3DSurface9_Release(rt);
12828     IDirect3DSurface9_Release(old_rt);
12829     IDirect3DPixelShader9_Release(ps);
12830     IDirect3DPixelShader9_Release(ps_cube);
12831     IDirect3DPixelShader9_Release(ps_volume);
12832 }
12833
12834 static void update_surface_test(IDirect3DDevice9 *device)
12835 {
12836     static const BYTE blocks[][8] =
12837     {
12838         {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
12839         {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
12840         {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
12841         {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
12842         {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
12843         {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
12844         {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
12845     };
12846     static const struct
12847     {
12848         UINT x, y;
12849         D3DCOLOR color;
12850     }
12851     expected_colors[] =
12852     {
12853         { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
12854         { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
12855         {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
12856         {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12857         {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12858         {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12859         {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
12860     };
12861     static const struct
12862     {
12863         float x, y, z, w;
12864         float u, v;
12865     }
12866     tri[] =
12867     {
12868         {  0.0f, 480.0f, 0.0f,  1.0f,   0.0f, 0.0f},
12869         {  0.0f,   0.0f, 0.0f,  1.0f,   0.0f, 1.0f},
12870         {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
12871     };
12872     static const RECT rect_2x2 = {0, 0, 2, 2};
12873     static const struct
12874     {
12875         UINT src_level;
12876         UINT dst_level;
12877         const RECT *r;
12878         HRESULT hr;
12879     }
12880     block_size_tests[] =
12881     {
12882         {1, 0, NULL,      D3D_OK},
12883         {0, 1, NULL,      D3DERR_INVALIDCALL},
12884         {5, 4, NULL,      D3DERR_INVALIDCALL},
12885         {4, 5, NULL,      D3DERR_INVALIDCALL},
12886         {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
12887         {5, 5, &rect_2x2, D3D_OK},
12888     };
12889
12890     IDirect3DSurface9 *src_surface, *dst_surface;
12891     IDirect3DTexture9 *src_tex, *dst_tex;
12892     IDirect3D9 *d3d;
12893     UINT count, i;
12894     HRESULT hr;
12895
12896     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12897     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12898
12899     hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12900             D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
12901     IDirect3D9_Release(d3d);
12902     if (FAILED(hr))
12903     {
12904         skip("DXT1 not supported, skipping test.\n");
12905         return;
12906     }
12907
12908     IDirect3D9_Release(d3d);
12909
12910     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
12911     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12912     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
12913     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12914
12915     count = IDirect3DTexture9_GetLevelCount(src_tex);
12916     ok(count == 7, "Got level count %u, expected 7.\n", count);
12917
12918     for (i = 0; i < count; ++i)
12919     {
12920         UINT row_count, block_count, x, y;
12921         D3DSURFACE_DESC desc;
12922         BYTE *row, *block;
12923         D3DLOCKED_RECT r;
12924
12925         hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
12926         ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
12927
12928         hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
12929         ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
12930
12931         row_count = ((desc.Height + 3) & ~3) / 4;
12932         block_count = ((desc.Width + 3) & ~3) / 4;
12933         row = r.pBits;
12934
12935         for (y = 0; y < row_count; ++y)
12936         {
12937             block = row;
12938             for (x = 0; x < block_count; ++x)
12939             {
12940                 memcpy(block, blocks[i], sizeof(blocks[i]));
12941                 block += sizeof(blocks[i]);
12942             }
12943             row += r.Pitch;
12944         }
12945
12946         hr = IDirect3DTexture9_UnlockRect(src_tex, i);
12947         ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
12948     }
12949
12950     for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
12951     {
12952         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
12953         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12954         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
12955         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12956
12957         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
12958         ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
12959                 hr, i, block_size_tests[i].hr);
12960
12961         IDirect3DSurface9_Release(dst_surface);
12962         IDirect3DSurface9_Release(src_surface);
12963     }
12964
12965     for (i = 0; i < count; ++i)
12966     {
12967         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
12968         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12969         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
12970         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12971
12972         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
12973         ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
12974
12975         IDirect3DSurface9_Release(dst_surface);
12976         IDirect3DSurface9_Release(src_surface);
12977     }
12978
12979     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12980     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12981     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12982     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12983     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
12984     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12985     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
12986     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12987     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12988     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12989     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12990     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12991
12992     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
12993     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12994
12995     hr = IDirect3DDevice9_BeginScene(device);
12996     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12997     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
12998     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12999     hr = IDirect3DDevice9_EndScene(device);
13000     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13001
13002     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13003     {
13004         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13005         ok(color_match(color, expected_colors[i].color, 0),
13006                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13007                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13008     }
13009
13010     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13011     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13012
13013     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13014     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13015     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
13016     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
13017     IDirect3DTexture9_Release(dst_tex);
13018     IDirect3DTexture9_Release(src_tex);
13019 }
13020
13021 static void multisample_get_rtdata_test(IDirect3DDevice9 *device)
13022 {
13023     IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
13024     IDirect3D9 *d3d9;
13025     HRESULT hr;
13026
13027     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
13028     ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
13029     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13030             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13031     IDirect3D9_Release(d3d9);
13032     if (FAILED(hr))
13033     {
13034         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
13035         return;
13036     }
13037
13038     hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
13039             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13040     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13041     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
13042             D3DPOOL_SYSTEMMEM, &readback, NULL);
13043     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13044
13045     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13046     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13047     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13048     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13049
13050     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13051     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13052     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13053     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13054
13055     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
13056     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13057     hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
13058     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
13059
13060     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13061     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13062     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13063     ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13064
13065     IDirect3DSurface9_Release(original_ds);
13066     IDirect3DSurface9_Release(original_rt);
13067     IDirect3DSurface9_Release(readback);
13068     IDirect3DSurface9_Release(rt);
13069 }
13070
13071 static void multisampled_depth_buffer_test(IDirect3D9 *d3d9)
13072 {
13073     IDirect3DDevice9 *device = 0;
13074     IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
13075     D3DCAPS9 caps;
13076     HRESULT hr;
13077     D3DPRESENT_PARAMETERS present_parameters;
13078     unsigned int i;
13079     static const struct
13080     {
13081         float x, y, z;
13082         D3DCOLOR color;
13083     }
13084     quad_1[] =
13085     {
13086         { -1.0f,  1.0f, 0.0f, 0xffff0000},
13087         {  1.0f,  1.0f, 1.0f, 0xffff0000},
13088         { -1.0f, -1.0f, 0.0f, 0xffff0000},
13089         {  1.0f, -1.0f, 1.0f, 0xffff0000},
13090     },
13091     quad_2[] =
13092     {
13093         { -1.0f,  1.0f, 1.0f, 0xff0000ff},
13094         {  1.0f,  1.0f, 0.0f, 0xff0000ff},
13095         { -1.0f, -1.0f, 1.0f, 0xff0000ff},
13096         {  1.0f, -1.0f, 0.0f, 0xff0000ff},
13097     };
13098     static const struct
13099     {
13100         UINT x, y;
13101         D3DCOLOR color;
13102     }
13103     expected_colors[] =
13104     {
13105         { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13106         {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13107         {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13108         {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13109         { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13110         {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13111         {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13112         {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13113     };
13114
13115     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13116             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13117     if (FAILED(hr))
13118     {
13119         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
13120         return;
13121     }
13122     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13123             D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13124     if (FAILED(hr))
13125     {
13126         skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
13127         return;
13128     }
13129
13130     ZeroMemory(&present_parameters, sizeof(present_parameters));
13131     present_parameters.Windowed = TRUE;
13132     present_parameters.hDeviceWindow = create_window();
13133     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13134     present_parameters.BackBufferWidth = 640;
13135     present_parameters.BackBufferHeight = 480;
13136     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13137     present_parameters.EnableAutoDepthStencil = TRUE;
13138     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13139     present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13140
13141     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13142             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13143             &present_parameters, &device);
13144     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13145
13146     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13147     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13148     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13149     {
13150         skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
13151         goto cleanup;
13152     }
13153
13154     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13155             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13156     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13157     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13158             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13159     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13160
13161     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13162     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13163     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13164     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13165
13166     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13167     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13168     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13169     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13170     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13171     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13172     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13173     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13174     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13175     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13176
13177     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13178     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13179
13180     /* Render onscreen and then offscreen */
13181     hr = IDirect3DDevice9_BeginScene(device);
13182     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13183     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13184     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13185     hr = IDirect3DDevice9_EndScene(device);
13186     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13187
13188     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
13189     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13190     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13191     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13192
13193     hr = IDirect3DDevice9_BeginScene(device);
13194     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13195     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13196     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13197     hr = IDirect3DDevice9_EndScene(device);
13198     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13199
13200     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
13201     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13202
13203     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13204     {
13205         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13206         ok(color_match(color, expected_colors[i].color, 1),
13207                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13208                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13209     }
13210
13211     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13212     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13213     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13214     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13215
13216     /* Render offscreen and then onscreen */
13217     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13218     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13219     IDirect3DSurface9_Release(ds);
13220     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13221             D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13222     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13223     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13224
13225     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13226     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13227
13228     hr = IDirect3DDevice9_BeginScene(device);
13229     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13230     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13231     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13232     hr = IDirect3DDevice9_EndScene(device);
13233     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13234
13235     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13236     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13237     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13238     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13239
13240     hr = IDirect3DDevice9_BeginScene(device);
13241     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13242     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13243     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13244     hr = IDirect3DDevice9_EndScene(device);
13245     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13246
13247     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13248     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13249
13250     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13251     {
13252         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13253         ok(color_match(color, expected_colors[i].color, 1),
13254                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13255                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13256     }
13257
13258     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13259     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13260
13261     IDirect3DSurface9_Release(ds);
13262     IDirect3DSurface9_Release(readback);
13263     IDirect3DSurface9_Release(rt);
13264     IDirect3DSurface9_Release(original_rt);
13265     cleanup_device(device);
13266
13267     ZeroMemory(&present_parameters, sizeof(present_parameters));
13268     present_parameters.Windowed = TRUE;
13269     present_parameters.hDeviceWindow = create_window();
13270     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13271     present_parameters.BackBufferWidth = 640;
13272     present_parameters.BackBufferHeight = 480;
13273     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13274     present_parameters.EnableAutoDepthStencil = TRUE;
13275     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13276     present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13277
13278     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13279             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13280             &present_parameters, &device);
13281     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13282
13283     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
13284     ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
13285
13286     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13287             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13288     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13289     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13290             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13291     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13292     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13293             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
13294     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13295
13296     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13297     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13298     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13299     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13300     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13301     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13302     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13303     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13304
13305     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13306     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13307     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13308     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13309     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13310     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13311     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13312     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13313     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13314     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13315
13316     /* Render to a multisampled offscreen frame buffer and then blit to
13317      * the onscreen (not multisampled) frame buffer. */
13318     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13319     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13320
13321     hr = IDirect3DDevice9_BeginScene(device);
13322     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13323     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13324     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13325     hr = IDirect3DDevice9_EndScene(device);
13326     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13327
13328     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13329     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13330     hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
13331     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13332
13333     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13334     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13335     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13336     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13337
13338     hr = IDirect3DDevice9_BeginScene(device);
13339     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13340     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13341     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13342     hr = IDirect3DDevice9_EndScene(device);
13343     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13344
13345     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13346     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13347
13348     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13349     {
13350         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13351         if (i % 4 < 2)
13352             todo_wine ok(color_match(color, expected_colors[i].color, 1),
13353                     "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13354                     expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13355         else
13356             ok(color_match(color, expected_colors[i].color, 1),
13357                     "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13358                     expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13359     }
13360
13361     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13362     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13363
13364     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13365     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13366     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13367     ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13368
13369     IDirect3DSurface9_Release(original_ds);
13370     IDirect3DSurface9_Release(original_rt);
13371     IDirect3DSurface9_Release(ds);
13372     IDirect3DSurface9_Release(readback);
13373     IDirect3DSurface9_Release(rt);
13374 cleanup:
13375     cleanup_device(device);
13376 }
13377
13378 static void resz_test(IDirect3D9 *d3d9)
13379 {
13380     IDirect3DDevice9 *device = 0;
13381     IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
13382     D3DCAPS9 caps;
13383     HRESULT hr;
13384     D3DPRESENT_PARAMETERS present_parameters;
13385     unsigned int i;
13386     static const DWORD ps_code[] =
13387     {
13388         0xffff0200,                                                             /* ps_2_0                       */
13389         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
13390         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
13391         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
13392         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
13393         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
13394         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
13395         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
13396         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
13397         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
13398         0x0000ffff,                                                             /* end                          */
13399     };
13400     struct
13401     {
13402         float x, y, z;
13403         float s, t, p, q;
13404     }
13405     quad[] =
13406     {
13407         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13408         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13409         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13410         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13411     };
13412     struct
13413     {
13414         UINT x, y;
13415         D3DCOLOR color;
13416     }
13417     expected_colors[] =
13418     {
13419         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13420         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13421         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13422         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13423         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13424         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13425         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13426         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13427     };
13428     IDirect3DTexture9 *texture;
13429     IDirect3DPixelShader9 *ps;
13430     DWORD value;
13431
13432     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13433             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13434     if (FAILED(hr))
13435     {
13436         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
13437         return;
13438     }
13439     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13440             D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13441     if (FAILED(hr))
13442     {
13443         skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
13444         return;
13445     }
13446
13447     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13448             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
13449     if (FAILED(hr))
13450     {
13451         skip("No INTZ support, skipping RESZ test.\n");
13452         return;
13453     }
13454
13455     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13456             D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'));
13457     if (FAILED(hr))
13458     {
13459         skip("No RESZ support, skipping RESZ test.\n");
13460         return;
13461     }
13462
13463     ZeroMemory(&present_parameters, sizeof(present_parameters));
13464     present_parameters.Windowed = TRUE;
13465     present_parameters.hDeviceWindow = create_window();
13466     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13467     present_parameters.BackBufferWidth = 640;
13468     present_parameters.BackBufferHeight = 480;
13469     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13470     present_parameters.EnableAutoDepthStencil = FALSE;
13471     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13472     present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13473
13474     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13475             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13476     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13477
13478     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13479     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13480     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
13481     {
13482         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
13483         cleanup_device(device);
13484         return;
13485     }
13486     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13487     {
13488         skip("No unconditional NP2 texture support, skipping INTZ test.\n");
13489         cleanup_device(device);
13490         return;
13491     }
13492
13493     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13494     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13495
13496     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13497             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13498     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13499     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13500             D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13501     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13502             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13503     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13504
13505     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13506             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13507     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13508     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13509     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13510     hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13511     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13512     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13513     ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13514     IDirect3DSurface9_Release(intz_ds);
13515     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13516     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13517
13518     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13519     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13520     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13521     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13522     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13523     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13524     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13525     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13526     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13527     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13528
13529     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13530     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13531     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13532     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13533     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13534     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13535     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13536     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13537     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13538     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13539
13540     /* Render offscreen (multisampled), blit the depth buffer
13541      * into the INTZ texture and then check its contents */
13542     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13543     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13544     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13545     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13546     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13547     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13548
13549     hr = IDirect3DDevice9_BeginScene(device);
13550     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13551     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13552     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13553
13554     /* The destination depth texture has to be bound to sampler 0 */
13555     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13556     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13557
13558     /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
13559     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13560     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13561     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13562     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13563     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13564     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13565     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13566     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13567     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13568     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13569     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13570     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13571     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13572     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13573
13574     /* The actual multisampled depth buffer resolve happens here */
13575     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13576     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13577     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13578     ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13579
13580     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13581     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13582     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13583     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13584
13585     /* Read the depth values back */
13586     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13587     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13588     hr = IDirect3DDevice9_EndScene(device);
13589     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13590
13591     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13592     {
13593         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13594         ok(color_match(color, expected_colors[i].color, 1),
13595                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13596                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13597     }
13598
13599     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13600     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13601
13602     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13603     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13604     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13605     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13606     IDirect3DSurface9_Release(ds);
13607     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13608     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13609     IDirect3DTexture9_Release(texture);
13610     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13611     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13612     IDirect3DPixelShader9_Release(ps);
13613     IDirect3DSurface9_Release(readback);
13614     IDirect3DSurface9_Release(original_rt);
13615     IDirect3DSurface9_Release(rt);
13616     cleanup_device(device);
13617
13618
13619     ZeroMemory(&present_parameters, sizeof(present_parameters));
13620     present_parameters.Windowed = TRUE;
13621     present_parameters.hDeviceWindow = create_window();
13622     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13623     present_parameters.BackBufferWidth = 640;
13624     present_parameters.BackBufferHeight = 480;
13625     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13626     present_parameters.EnableAutoDepthStencil = TRUE;
13627     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13628     present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13629
13630     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13631             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13632     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13633
13634     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13635     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13636     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13637     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13638     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13639             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13640     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13641     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13642             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13643     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13644     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13645     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13646     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13647     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13648     hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13649     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13650     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13651     ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13652     IDirect3DSurface9_Release(intz_ds);
13653     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13654     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13655
13656     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13657     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13658     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13659     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13660     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13661     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13662     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13663     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13664     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13665     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13666
13667     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13668     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13669     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13670     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13671     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13672     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13673     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13674     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13675     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13676     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13677
13678     /* Render onscreen, blit the depth buffer into the INTZ texture
13679      * and then check its contents */
13680     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13681     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13682     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13683     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13684     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13685     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13686
13687     hr = IDirect3DDevice9_BeginScene(device);
13688     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13689     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13690     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13691     hr = IDirect3DDevice9_EndScene(device);
13692     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13693
13694     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13695     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13696
13697     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13698     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13699     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13700     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13701     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13702     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13703     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13704     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13705     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13706     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13707     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13708     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13709     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13710     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13711
13712     /* The actual multisampled depth buffer resolve happens here */
13713     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13714     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13715     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13716     ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13717
13718     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13719     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13720     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13721     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13722
13723     /* Read the depth values back */
13724     hr = IDirect3DDevice9_BeginScene(device);
13725     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13726     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13727     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13728     hr = IDirect3DDevice9_EndScene(device);
13729     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13730
13731     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13732     {
13733         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13734         ok(color_match(color, expected_colors[i].color, 1),
13735                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13736                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13737     }
13738
13739     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13740     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13741
13742
13743     /* Test edge cases - try with no texture at all */
13744     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13745     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13746     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13747     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13748
13749     hr = IDirect3DDevice9_BeginScene(device);
13750     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13751     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13752     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13753     hr = IDirect3DDevice9_EndScene(device);
13754     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13755
13756     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13757     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13758
13759     /* With a non-multisampled depth buffer */
13760     IDirect3DSurface9_Release(ds);
13761     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13762             D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
13763
13764     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13765     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13766     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13767     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13768     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13769     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13770
13771     hr = IDirect3DDevice9_BeginScene(device);
13772     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13773     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13774     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13775
13776     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13777     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13778
13779     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13780     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13781     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13782     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13783     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13784     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13785     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13786     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13787     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13788     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13789     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13790     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13791     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13792     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13793     hr = IDirect3DDevice9_EndScene(device);
13794     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13795
13796     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13797     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13798
13799     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13800     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13801
13802     /* Read the depth values back. */
13803     hr = IDirect3DDevice9_BeginScene(device);
13804     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13805     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13806     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13807     hr = IDirect3DDevice9_EndScene(device);
13808     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13809
13810     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13811     {
13812         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13813         ok(color_match(color, expected_colors[i].color, 1),
13814                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13815                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13816     }
13817
13818     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13819     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13820
13821     /* Without a current depth-stencil buffer set */
13822     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13823     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13824     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13825     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13826
13827     hr = IDirect3DDevice9_BeginScene(device);
13828     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13829     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13830     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13831     hr = IDirect3DDevice9_EndScene(device);
13832     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13833
13834     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13835     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13836
13837     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13838     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13839     IDirect3DSurface9_Release(ds);
13840     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13841     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13842     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13843     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13844     IDirect3DTexture9_Release(texture);
13845     IDirect3DPixelShader9_Release(ps);
13846     IDirect3DSurface9_Release(readback);
13847     IDirect3DSurface9_Release(original_rt);
13848     cleanup_device(device);
13849 }
13850
13851 static void zenable_test(IDirect3DDevice9 *device)
13852 {
13853     static const struct
13854     {
13855         struct vec4 position;
13856         D3DCOLOR diffuse;
13857     }
13858     tquad[] =
13859     {
13860         {{  0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
13861         {{  0.0f,   0.0f, -0.5f, 1.0f}, 0xff00ff00},
13862         {{640.0f, 480.0f,  1.5f, 1.0f}, 0xff00ff00},
13863         {{640.0f,   0.0f,  1.5f, 1.0f}, 0xff00ff00},
13864     };
13865     D3DCOLOR color;
13866     D3DCAPS9 caps;
13867     HRESULT hr;
13868     UINT x, y;
13869     UINT i, j;
13870
13871     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
13872     ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
13873     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13874     ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
13875
13876     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
13877     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13878     hr = IDirect3DDevice9_BeginScene(device);
13879     ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13880     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
13881     ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13882     hr = IDirect3DDevice9_EndScene(device);
13883     ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13884
13885     for (i = 0; i < 4; ++i)
13886     {
13887         for (j = 0; j < 4; ++j)
13888         {
13889             x = 80 * ((2 * j) + 1);
13890             y = 60 * ((2 * i) + 1);
13891             color = getPixelColor(device, x, y);
13892             ok(color_match(color, 0x0000ff00, 1),
13893                     "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
13894         }
13895     }
13896
13897     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13898     ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
13899
13900     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13901     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13902
13903     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
13904             && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
13905     {
13906         static const DWORD vs_code[] =
13907         {
13908             0xfffe0101,                                 /* vs_1_1           */
13909             0x0000001f, 0x80000000, 0x900f0000,         /* dcl_position v0  */
13910             0x00000001, 0xc00f0000, 0x90e40000,         /* mov oPos, v0     */
13911             0x00000001, 0xd00f0000, 0x90e40000,         /* mov oD0, v0      */
13912             0x0000ffff
13913         };
13914         static const DWORD ps_code[] =
13915         {
13916             0xffff0101,                                 /* ps_1_1           */
13917             0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
13918             0x0000ffff                                  /* end              */
13919         };
13920         static const struct vec3 quad[] =
13921         {
13922             {-1.0f, -1.0f, -0.5f},
13923             {-1.0f,  1.0f, -0.5f},
13924             { 1.0f, -1.0f,  1.5f},
13925             { 1.0f,  1.0f,  1.5f},
13926         };
13927         static const D3DCOLOR expected[] =
13928         {
13929             0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
13930             0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
13931             0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
13932             0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
13933         };
13934
13935         IDirect3DVertexShader9 *vs;
13936         IDirect3DPixelShader9 *ps;
13937
13938         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13939         ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
13940         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
13941         ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
13942         hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13943         ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
13944         hr = IDirect3DDevice9_SetVertexShader(device, vs);
13945         ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13946         hr = IDirect3DDevice9_SetPixelShader(device, ps);
13947         ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
13948
13949         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
13950         ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13951         hr = IDirect3DDevice9_BeginScene(device);
13952         ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13953         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13954         ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13955         hr = IDirect3DDevice9_EndScene(device);
13956         ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13957
13958         for (i = 0; i < 4; ++i)
13959         {
13960             for (j = 0; j < 4; ++j)
13961             {
13962                 x = 80 * ((2 * j) + 1);
13963                 y = 60 * ((2 * i) + 1);
13964                 color = getPixelColor(device, x, y);
13965                 ok(color_match(color, expected[i * 4 + j], 1),
13966                         "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
13967             }
13968         }
13969
13970         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13971         ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
13972
13973         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13974         ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
13975         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
13976         ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13977         IDirect3DPixelShader9_Release(ps);
13978         IDirect3DVertexShader9_Release(vs);
13979     }
13980 }
13981
13982 START_TEST(visual)
13983 {
13984     IDirect3D9 *d3d9;
13985     IDirect3DDevice9 *device_ptr;
13986     D3DCAPS9 caps;
13987     HRESULT hr;
13988     DWORD color;
13989
13990     d3d9_handle = LoadLibraryA("d3d9.dll");
13991     if (!d3d9_handle)
13992     {
13993         skip("Could not load d3d9.dll\n");
13994         return;
13995     }
13996
13997     device_ptr = init_d3d9();
13998     if (!device_ptr)
13999     {
14000         skip("Creating the device failed\n");
14001         return;
14002     }
14003
14004     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
14005
14006     /* Check for the reliability of the returned data */
14007     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
14008     if(FAILED(hr))
14009     {
14010         skip("Clear failed, can't assure correctness of the test results, skipping\n");
14011         goto cleanup;
14012     }
14013
14014     color = getPixelColor(device_ptr, 1, 1);
14015     if(color !=0x00ff0000)
14016     {
14017         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
14018         goto cleanup;
14019     }
14020     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
14021
14022     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
14023     if(FAILED(hr))
14024     {
14025         skip("Clear failed, can't assure correctness of the test results, skipping\n");
14026         goto cleanup;
14027     }
14028
14029     color = getPixelColor(device_ptr, 639, 479);
14030     if(color != 0x0000ddee)
14031     {
14032         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
14033         goto cleanup;
14034     }
14035     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
14036
14037     /* Now execute the real tests */
14038     depth_clamp_test(device_ptr);
14039     stretchrect_test(device_ptr);
14040     lighting_test(device_ptr);
14041     clear_test(device_ptr);
14042     color_fill_test(device_ptr);
14043     fog_test(device_ptr);
14044     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
14045     {
14046         test_cube_wrap(device_ptr);
14047     } else {
14048         skip("No cube texture support\n");
14049     }
14050     z_range_test(device_ptr);
14051     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
14052     {
14053         maxmip_test(device_ptr);
14054     }
14055     else
14056     {
14057         skip("No mipmap support\n");
14058     }
14059     offscreen_test(device_ptr);
14060     ds_size_test(device_ptr);
14061     alpha_test(device_ptr);
14062     shademode_test(device_ptr);
14063     srgbtexture_test(device_ptr);
14064     release_buffer_test(device_ptr);
14065     float_texture_test(device_ptr);
14066     g16r16_texture_test(device_ptr);
14067     pixelshader_blending_test(device_ptr);
14068     texture_transform_flags_test(device_ptr);
14069     autogen_mipmap_test(device_ptr);
14070     fixed_function_decl_test(device_ptr);
14071     conditional_np2_repeat_test(device_ptr);
14072     fixed_function_bumpmap_test(device_ptr);
14073     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
14074         stencil_cull_test(device_ptr);
14075     } else {
14076         skip("No two sided stencil support\n");
14077     }
14078     pointsize_test(device_ptr);
14079     tssargtemp_test(device_ptr);
14080     np2_stretch_rect_test(device_ptr);
14081     yuv_color_test(device_ptr);
14082     zwriteenable_test(device_ptr);
14083     alphatest_test(device_ptr);
14084     viewport_test(device_ptr);
14085
14086     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
14087     {
14088         test_constant_clamp_vs(device_ptr);
14089         test_compare_instructions(device_ptr);
14090     }
14091     else skip("No vs_1_1 support\n");
14092
14093     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
14094     {
14095         test_mova(device_ptr);
14096         loop_index_test(device_ptr);
14097         sincos_test(device_ptr);
14098         sgn_test(device_ptr);
14099         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14100             test_vshader_input(device_ptr);
14101             test_vshader_float16(device_ptr);
14102             stream_test(device_ptr);
14103         } else {
14104             skip("No vs_3_0 support\n");
14105         }
14106     }
14107     else skip("No vs_2_0 support\n");
14108
14109     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0) && caps.PixelShaderVersion >= D3DPS_VERSION(2, 0))
14110     {
14111         fog_with_shader_test(device_ptr);
14112     }
14113     else skip("No vs_2_0 and ps_2_0 support\n");
14114
14115     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
14116     {
14117         texbem_test(device_ptr);
14118         texdepth_test(device_ptr);
14119         texkill_test(device_ptr);
14120         x8l8v8u8_test(device_ptr);
14121         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
14122             constant_clamp_ps_test(device_ptr);
14123             cnd_test(device_ptr);
14124             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
14125                 dp2add_ps_test(device_ptr);
14126                 unbound_sampler_test(device_ptr);
14127                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14128                     nested_loop_test(device_ptr);
14129                     pretransformed_varying_test(device_ptr);
14130                     vFace_register_test(device_ptr);
14131                     vpos_register_test(device_ptr);
14132                     multiple_rendertargets_test(device_ptr);
14133                 } else {
14134                     skip("No ps_3_0 or vs_3_0 support\n");
14135                 }
14136             } else {
14137                 skip("No ps_2_0 support\n");
14138             }
14139         }
14140     }
14141     else skip("No ps_1_1 support\n");
14142
14143     texop_test(device_ptr);
14144     texop_range_test(device_ptr);
14145     alphareplicate_test(device_ptr);
14146     dp3_alpha_test(device_ptr);
14147     depth_buffer_test(device_ptr);
14148     depth_buffer2_test(device_ptr);
14149     depth_blit_test(device_ptr);
14150     intz_test(device_ptr);
14151     shadow_test(device_ptr);
14152     fp_special_test(device_ptr);
14153     depth_bounds_test(device_ptr);
14154     srgbwrite_format_test(device_ptr);
14155     clip_planes_test(device_ptr);
14156     update_surface_test(device_ptr);
14157     multisample_get_rtdata_test(device_ptr);
14158     zenable_test(device_ptr);
14159
14160     hr = IDirect3DDevice9_GetDirect3D(device_ptr, &d3d9);
14161     ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
14162     cleanup_device(device_ptr);
14163     device_ptr = NULL;
14164
14165     multisampled_depth_buffer_test(d3d9);
14166     resz_test(d3d9);
14167
14168     IDirect3D9_Release(d3d9);
14169
14170 cleanup:
14171     cleanup_device(device_ptr);
14172 }