wined3d: Recognize Nvidia GT520 cards.
[wine] / dlls / d3d9 / tests / visual.c
1 /*
2  * Copyright 2005, 2007-2008 Henri Verbeet
3  * Copyright (C) 2007-2008 Stefan Dösinger(for CodeWeavers)
4  * Copyright (C) 2008 Jason Green(for TransGaming)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22  * the framebuffer, read back from there and compared to expected colors.
23  *
24  * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25  * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26  * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27  * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28  * causes visible results in games can be tested in a way that does not depend on pixel exactness
29  */
30
31 #define COBJMACROS
32 #include <d3d9.h>
33 #include "wine/test.h"
34
35 static HMODULE d3d9_handle = 0;
36
37 struct vec3
38 {
39     float x, y, z;
40 };
41
42 struct vec4
43 {
44     float x, y, z, w;
45 };
46
47 static HWND create_window(void)
48 {
49     WNDCLASS wc = {0};
50     HWND ret;
51     wc.lpfnWndProc = DefWindowProc;
52     wc.lpszClassName = "d3d9_test_wc";
53     RegisterClass(&wc);
54
55     ret = CreateWindow("d3d9_test_wc", "d3d9_test",
56                         WS_SYSMENU | WS_POPUP , 0, 0, 640, 480, 0, 0, 0, 0);
57     ShowWindow(ret, SW_SHOW);
58     return ret;
59 }
60
61 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
62 {
63     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
64     c1 >>= 8; c2 >>= 8;
65     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
66     c1 >>= 8; c2 >>= 8;
67     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
68     c1 >>= 8; c2 >>= 8;
69     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
70     return TRUE;
71 }
72
73 /* Locks a given surface and returns the color at (x,y).  It's the caller's
74  * responsibility to only pass in lockable surfaces and valid x,y coordinates */
75 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
76 {
77     DWORD color;
78     HRESULT hr;
79     D3DSURFACE_DESC desc;
80     RECT rectToLock = {x, y, x+1, y+1};
81     D3DLOCKED_RECT lockedRect;
82
83     hr = IDirect3DSurface9_GetDesc(surface, &desc);
84     if(FAILED(hr))  /* This is not a test */
85     {
86         trace("Can't get the surface description, hr=%08x\n", hr);
87         return 0xdeadbeef;
88     }
89
90     hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
91     if(FAILED(hr))  /* This is not a test */
92     {
93         trace("Can't lock the surface, hr=%08x\n", hr);
94         return 0xdeadbeef;
95     }
96     switch(desc.Format) {
97         case D3DFMT_A8R8G8B8:
98         {
99             color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
100             break;
101         }
102         default:
103             trace("Error: unknown surface format: %d\n", desc.Format);
104             color = 0xdeadbeef;
105             break;
106     }
107     hr = IDirect3DSurface9_UnlockRect(surface);
108     if(FAILED(hr))
109     {
110         trace("Can't unlock the surface, hr=%08x\n", hr);
111     }
112     return color;
113 }
114
115 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
116 {
117     DWORD ret;
118     IDirect3DSurface9 *surf = NULL, *target = NULL;
119     HRESULT hr;
120     D3DLOCKED_RECT lockedRect;
121     RECT rectToLock = {x, y, x+1, y+1};
122
123     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480,
124             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
125     if (FAILED(hr) || !surf)
126     {
127         trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
128         return 0xdeadbeef;
129     }
130
131     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
132     if(FAILED(hr))
133     {
134         trace("Can't get the render target, hr=%08x\n", hr);
135         ret = 0xdeadbeed;
136         goto out;
137     }
138
139     hr = IDirect3DDevice9_GetRenderTargetData(device, target, surf);
140     if (FAILED(hr))
141     {
142         trace("Can't read the render target data, hr=%08x\n", hr);
143         ret = 0xdeadbeec;
144         goto out;
145     }
146
147     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
148     if(FAILED(hr))
149     {
150         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
151         ret = 0xdeadbeeb;
152         goto out;
153     }
154
155     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
156      * really important for these tests
157      */
158     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
159     hr = IDirect3DSurface9_UnlockRect(surf);
160     if(FAILED(hr))
161     {
162         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
163     }
164
165 out:
166     if(target) IDirect3DSurface9_Release(target);
167     if(surf) IDirect3DSurface9_Release(surf);
168     return ret;
169 }
170
171 static IDirect3DDevice9 *init_d3d9(void)
172 {
173     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
174     IDirect3D9 *d3d9_ptr = 0;
175     IDirect3DDevice9 *device_ptr = 0;
176     D3DPRESENT_PARAMETERS present_parameters;
177     HRESULT hr;
178     D3DADAPTER_IDENTIFIER9 identifier;
179
180     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
181     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
182     if (!d3d9_create) return NULL;
183
184     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
185     if (!d3d9_ptr)
186     {
187         win_skip("could not create D3D9\n");
188         return NULL;
189     }
190
191     ZeroMemory(&present_parameters, sizeof(present_parameters));
192     present_parameters.Windowed = TRUE;
193     present_parameters.hDeviceWindow = create_window();
194     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
195     present_parameters.BackBufferWidth = 640;
196     present_parameters.BackBufferHeight = 480;
197     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
198     present_parameters.EnableAutoDepthStencil = TRUE;
199     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
200
201     memset(&identifier, 0, sizeof(identifier));
202     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
203     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
204     trace("Driver string: \"%s\"\n", identifier.Driver);
205     trace("Description string: \"%s\"\n", identifier.Description);
206     ok(identifier.Description[0] != '\0', "Empty driver description\n");
207     trace("Device name string: \"%s\"\n", identifier.DeviceName);
208     ok(identifier.DeviceName[0]  != '\0', "Empty device name\n");
209     trace("Driver version %d.%d.%d.%d\n",
210           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
211           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
212
213     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
214             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
215     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
216             "Failed to create a device, hr %#x.\n", hr);
217
218     return device_ptr;
219 }
220
221 static void cleanup_device(IDirect3DDevice9 *device)
222 {
223     if (device)
224     {
225         D3DPRESENT_PARAMETERS present_parameters;
226         IDirect3DSwapChain9 *swapchain;
227         ULONG ref;
228
229         IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
230         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
231         IDirect3DSwapChain9_Release(swapchain);
232         ref = IDirect3DDevice9_Release(device);
233         ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
234         DestroyWindow(present_parameters.hDeviceWindow);
235     }
236 }
237
238 struct vertex
239 {
240     float x, y, z;
241     DWORD diffuse;
242 };
243
244 struct tvertex
245 {
246     float x, y, z, rhw;
247     DWORD diffuse;
248 };
249
250 struct nvertex
251 {
252     float x, y, z;
253     float nx, ny, nz;
254     DWORD diffuse;
255 };
256
257 static void lighting_test(IDirect3DDevice9 *device)
258 {
259     HRESULT hr;
260     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
261     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
262     DWORD color;
263     D3DMATERIAL9 material, old_material;
264     DWORD cop, carg;
265     DWORD old_colorwrite;
266
267     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
268                       0.0f, 1.0f, 0.0f, 0.0f,
269                       0.0f, 0.0f, 1.0f, 0.0f,
270                       0.0f, 0.0f, 0.0f, 1.0f };
271
272     struct vertex unlitquad[] =
273     {
274         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
275         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
276         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
277         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
278     };
279     struct vertex litquad[] =
280     {
281         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
282         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
283         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
284         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
285     };
286     struct nvertex unlitnquad[] =
287     {
288         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
289         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
290         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
291         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
292     };
293     struct nvertex litnquad[] =
294     {
295         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
296         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
297         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
298         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
299     };
300     WORD Indices[] = {0, 1, 2, 2, 3, 0};
301
302     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
303     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
304
305     /* Setup some states that may cause issues */
306     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
307     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
308     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
309     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
310     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
311     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
312     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
313     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
314     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
315     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
316     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
317     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
318     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
319     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
320     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
321     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
322     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
323     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
324     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
325     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
326     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
327     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
328     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &old_colorwrite);
329     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
330     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
331     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
332
333     hr = IDirect3DDevice9_SetFVF(device, 0);
334     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
335
336     hr = IDirect3DDevice9_SetFVF(device, fvf);
337     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
338
339     hr = IDirect3DDevice9_BeginScene(device);
340     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
341     if(hr == D3D_OK)
342     {
343         /* No lights are defined... That means, lit vertices should be entirely black */
344         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
345         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
346         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
347                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
348         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
349
350         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
351         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
352         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
353                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
354         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
355
356         hr = IDirect3DDevice9_SetFVF(device, nfvf);
357         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
358
359         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
360         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
361         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
362                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
363         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
364
365         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
366         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
367         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
368                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
369         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
370
371         hr = IDirect3DDevice9_EndScene(device);
372         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
373     }
374
375     color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
376     ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
377     color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
378     ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
379     color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
380     ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
381     color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
382     ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
383
384     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
385
386     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
387     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
388     memset(&material, 0, sizeof(material));
389     material.Diffuse.r = 0.0;
390     material.Diffuse.g = 0.0;
391     material.Diffuse.b = 0.0;
392     material.Diffuse.a = 1.0;
393     material.Ambient.r = 0.0;
394     material.Ambient.g = 0.0;
395     material.Ambient.b = 0.0;
396     material.Ambient.a = 0.0;
397     material.Specular.r = 0.0;
398     material.Specular.g = 0.0;
399     material.Specular.b = 0.0;
400     material.Specular.a = 0.0;
401     material.Emissive.r = 0.0;
402     material.Emissive.g = 0.0;
403     material.Emissive.b = 0.0;
404     material.Emissive.a = 0.0;
405     material.Power = 0.0;
406     hr = IDirect3DDevice9_SetMaterial(device, &material);
407     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
408
409     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
410     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
411     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
412     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
413
414     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
415     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
416     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
417     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
418     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
419     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
420     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
421     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
422
423     hr = IDirect3DDevice9_BeginScene(device);
424     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
425     if(SUCCEEDED(hr)) {
426         struct vertex lighting_test[] = {
427             {-1.0,   -1.0,   0.1,    0x8000ff00},
428             { 1.0,   -1.0,   0.1,    0x80000000},
429             {-1.0,    1.0,   0.1,    0x8000ff00},
430             { 1.0,    1.0,   0.1,    0x80000000}
431         };
432         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
433         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
434         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
435         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
436
437         hr = IDirect3DDevice9_EndScene(device);
438         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
439     }
440
441     color = getPixelColor(device, 320, 240);
442     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
443     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
444
445     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
446     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
447     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
448     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
449     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
450     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
451     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
452     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
453     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, old_colorwrite);
454     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
455     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
456     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
457     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
458     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
459 }
460
461 static void clear_test(IDirect3DDevice9 *device)
462 {
463     /* Tests the correctness of clearing parameters */
464     HRESULT hr;
465     D3DRECT rect[2];
466     D3DRECT rect_negneg;
467     DWORD color;
468     D3DVIEWPORT9 old_vp, vp;
469     RECT scissor;
470     DWORD oldColorWrite;
471     BOOL invalid_clear_failed = FALSE;
472
473     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
474     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
475
476     /* Positive x, negative y */
477     rect[0].x1 = 0;
478     rect[0].y1 = 480;
479     rect[0].x2 = 320;
480     rect[0].y2 = 240;
481
482     /* Positive x, positive y */
483     rect[1].x1 = 0;
484     rect[1].y1 = 0;
485     rect[1].x2 = 320;
486     rect[1].y2 = 240;
487     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
488      * returns D3D_OK, but ignores the rectangle silently
489      */
490     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
491     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
492     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
493
494     /* negative x, negative y */
495     rect_negneg.x1 = 640;
496     rect_negneg.y1 = 240;
497     rect_negneg.x2 = 320;
498     rect_negneg.y2 = 0;
499     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
500     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
501     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
502
503     color = getPixelColor(device, 160, 360); /* lower left quad */
504     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
505     color = getPixelColor(device, 160, 120); /* upper left quad */
506     if(invalid_clear_failed) {
507         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
508         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
509     } else {
510         /* If the negative rectangle was dropped silently, the correct ones are cleared */
511         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
512     }
513     color = getPixelColor(device, 480, 360); /* lower right quad  */
514     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
515     color = getPixelColor(device, 480, 120); /* upper right quad */
516     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
517
518     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
519
520     /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
521      * clear the red quad in the top left part of the render target. For some reason it
522      * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
523      * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
524      * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
525      * pick some obvious value
526      */
527     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
528     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
529
530     /* Test how the viewport affects clears */
531     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
532     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
533     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
534     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
535
536     vp.X = 160;
537     vp.Y = 120;
538     vp.Width = 160;
539     vp.Height = 120;
540     vp.MinZ = 0.0;
541     vp.MaxZ = 1.0;
542     hr = IDirect3DDevice9_SetViewport(device, &vp);
543     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
544     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
545     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
546
547     vp.X = 320;
548     vp.Y = 240;
549     vp.Width = 320;
550     vp.Height = 240;
551     vp.MinZ = 0.0;
552     vp.MaxZ = 1.0;
553     hr = IDirect3DDevice9_SetViewport(device, &vp);
554     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
555     rect[0].x1 = 160;
556     rect[0].y1 = 120;
557     rect[0].x2 = 480;
558     rect[0].y2 = 360;
559     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
560     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
561
562     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
563     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
564
565     color = getPixelColor(device, 158, 118);
566     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
567     color = getPixelColor(device, 162, 118);
568     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
569     color = getPixelColor(device, 158, 122);
570     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
571     color = getPixelColor(device, 162, 122);
572     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
573
574     color = getPixelColor(device, 318, 238);
575     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
576     color = getPixelColor(device, 322, 238);
577     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
578     color = getPixelColor(device, 318, 242);
579     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
580     color = getPixelColor(device, 322, 242);
581     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
582
583     color = getPixelColor(device, 478, 358);
584     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
585     color = getPixelColor(device, 482, 358);
586     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
587     color = getPixelColor(device, 478, 362);
588     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
589     color = getPixelColor(device, 482, 362);
590     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
591
592     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
593
594     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
595     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
596
597     scissor.left = 160;
598     scissor.right = 480;
599     scissor.top = 120;
600     scissor.bottom = 360;
601     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
602     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
603     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
604     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
605
606     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
607     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
608     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
609     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
610
611     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
612     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
613
614     color = getPixelColor(device, 158, 118);
615     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
616     color = getPixelColor(device, 162, 118);
617     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
618     color = getPixelColor(device, 158, 122);
619     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
620     color = getPixelColor(device, 162, 122);
621     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
622
623     color = getPixelColor(device, 158, 358);
624     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
625     color = getPixelColor(device, 162, 358);
626     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
627     color = getPixelColor(device, 158, 358);
628     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
629     color = getPixelColor(device, 162, 362);
630     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
631
632     color = getPixelColor(device, 478, 118);
633     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
634     color = getPixelColor(device, 478, 122);
635     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
636     color = getPixelColor(device, 482, 122);
637     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
638     color = getPixelColor(device, 482, 358);
639     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
640
641     color = getPixelColor(device, 478, 358);
642     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
643     color = getPixelColor(device, 478, 362);
644     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
645     color = getPixelColor(device, 482, 358);
646     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
647     color = getPixelColor(device, 482, 362);
648     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
649
650     color = getPixelColor(device, 318, 238);
651     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
652     color = getPixelColor(device, 318, 242);
653     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
654     color = getPixelColor(device, 322, 238);
655     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
656     color = getPixelColor(device, 322, 242);
657     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
658
659     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
660
661     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
662     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
663     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
664     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
665
666     /* Same nvidia windows driver trouble with white clears as earlier in the same test */
667     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
668     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
669
670     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
671     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
672
673     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
674     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
675
676     /* Colorwriteenable does not affect the clear */
677     color = getPixelColor(device, 320, 240);
678     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
679
680     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
681 }
682
683 static void color_fill_test(IDirect3DDevice9 *device)
684 {
685     HRESULT hr;
686     IDirect3DSurface9 *backbuffer = NULL;
687     IDirect3DSurface9 *rt_surface = NULL;
688     IDirect3DSurface9 *offscreen_surface = NULL;
689     DWORD fill_color, color;
690
691     /* Test ColorFill on a the backbuffer (should pass) */
692     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
693     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
694     if(backbuffer)
695     {
696         fill_color = 0x112233;
697         hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
698         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
699
700         color = getPixelColor(device, 0, 0);
701         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
702
703         IDirect3DSurface9_Release(backbuffer);
704     }
705
706     /* Test ColorFill on a render target surface (should pass) */
707     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
708     ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
709     if(rt_surface)
710     {
711         fill_color = 0x445566;
712         hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
713         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
714
715         color = getPixelColorFromSurface(rt_surface, 0, 0);
716         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
717
718         IDirect3DSurface9_Release(rt_surface);
719     }
720
721     /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
722     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
723             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
724     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
725     if(offscreen_surface)
726     {
727         fill_color = 0x778899;
728         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
729         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
730
731         color = getPixelColorFromSurface(offscreen_surface, 0, 0);
732         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
733
734         IDirect3DSurface9_Release(offscreen_surface);
735     }
736
737     /* Try ColorFill on a offscreen surface in sysmem (should fail) */
738     offscreen_surface = NULL;
739     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
740             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
741     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
742     if(offscreen_surface)
743     {
744         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
745         ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
746
747         IDirect3DSurface9_Release(offscreen_surface);
748     }
749 }
750
751 typedef struct {
752     float in[4];
753     DWORD out;
754 } test_data_t;
755
756 /*
757  *  c7      mova    ARGB            mov     ARGB
758  * -2.4     -2      0x00ffff00      -3      0x00ff0000
759  * -1.6     -2      0x00ffff00      -2      0x00ffff00
760  * -0.4      0      0x0000ffff      -1      0x0000ff00
761  *  0.4      0      0x0000ffff       0      0x0000ffff
762  *  1.6      2      0x00ff00ff       1      0x000000ff
763  *  2.4      2      0x00ff00ff       2      0x00ff00ff
764  */
765 static void test_mova(IDirect3DDevice9 *device)
766 {
767     static const DWORD mova_test[] = {
768         0xfffe0200,                                                             /* vs_2_0                       */
769         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
770         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
771         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
772         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
773         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
774         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
775         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
776         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
777         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
778         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
779         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
780         0x0000ffff                                                              /* END                          */
781     };
782     static const DWORD mov_test[] = {
783         0xfffe0101,                                                             /* vs_1_1                       */
784         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
785         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
786         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
787         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
788         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
789         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
790         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
791         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
792         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
793         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
794         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
795         0x0000ffff                                                              /* END                          */
796     };
797
798     static const test_data_t test_data[2][6] = {
799         {
800             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
801             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
802             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
803             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
804             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
805             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
806         },
807         {
808             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
809             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
810             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
811             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
812             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
813             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
814         }
815     };
816
817     static const float quad[][3] = {
818         {-1.0f, -1.0f, 0.0f},
819         {-1.0f,  1.0f, 0.0f},
820         { 1.0f, -1.0f, 0.0f},
821         { 1.0f,  1.0f, 0.0f},
822     };
823
824     static const D3DVERTEXELEMENT9 decl_elements[] = {
825         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
826         D3DDECL_END()
827     };
828
829     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
830     IDirect3DVertexShader9 *mova_shader = NULL;
831     IDirect3DVertexShader9 *mov_shader = NULL;
832     HRESULT hr;
833     UINT i, j;
834
835     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
836     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
837     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
838     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
839     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
840     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
841     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
842     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
843
844     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
845     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
846     for(j = 0; j < 2; ++j)
847     {
848         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
849         {
850             DWORD color;
851
852             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
853             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
854
855             hr = IDirect3DDevice9_BeginScene(device);
856             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
857
858             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
859             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
860
861             hr = IDirect3DDevice9_EndScene(device);
862             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
863
864             color = getPixelColor(device, 320, 240);
865             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
866                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
867
868             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
869             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
870
871             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
872             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
873         }
874         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
875         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
876     }
877
878     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
879     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
880
881     IDirect3DVertexDeclaration9_Release(vertex_declaration);
882     IDirect3DVertexShader9_Release(mova_shader);
883     IDirect3DVertexShader9_Release(mov_shader);
884 }
885
886 struct sVertex {
887     float x, y, z;
888     DWORD diffuse;
889     DWORD specular;
890 };
891
892 struct sVertexT {
893     float x, y, z, rhw;
894     DWORD diffuse;
895     DWORD specular;
896 };
897
898 static void fog_test(IDirect3DDevice9 *device)
899 {
900     HRESULT hr;
901     D3DCOLOR color;
902     float start = 0.0f, end = 1.0f;
903     D3DCAPS9 caps;
904     int i;
905
906     /* Gets full z based fog with linear fog, no fog with specular color */
907     struct sVertex untransformed_1[] = {
908         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
909         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
910         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
911         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
912     };
913     /* Ok, I am too lazy to deal with transform matrices */
914     struct sVertex untransformed_2[] = {
915         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
916         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
917         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
918         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
919     };
920     /* Untransformed ones. Give them a different diffuse color to make the test look
921      * nicer. It also makes making sure that they are drawn correctly easier.
922      */
923     struct sVertexT transformed_1[] = {
924         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
925         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
926         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
927         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
928     };
929     struct sVertexT transformed_2[] = {
930         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
931         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
932         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
933         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
934     };
935     struct vertex rev_fog_quads[] = {
936        {-1.0,   -1.0,   0.1,    0x000000ff},
937        {-1.0,    0.0,   0.1,    0x000000ff},
938        { 0.0,    0.0,   0.1,    0x000000ff},
939        { 0.0,   -1.0,   0.1,    0x000000ff},
940
941        { 0.0,   -1.0,   0.9,    0x000000ff},
942        { 0.0,    0.0,   0.9,    0x000000ff},
943        { 1.0,    0.0,   0.9,    0x000000ff},
944        { 1.0,   -1.0,   0.9,    0x000000ff},
945
946        { 0.0,    0.0,   0.4,    0x000000ff},
947        { 0.0,    1.0,   0.4,    0x000000ff},
948        { 1.0,    1.0,   0.4,    0x000000ff},
949        { 1.0,    0.0,   0.4,    0x000000ff},
950
951        {-1.0,    0.0,   0.7,    0x000000ff},
952        {-1.0,    1.0,   0.7,    0x000000ff},
953        { 0.0,    1.0,   0.7,    0x000000ff},
954        { 0.0,    0.0,   0.7,    0x000000ff},
955     };
956     WORD Indices[] = {0, 1, 2, 2, 3, 0};
957
958     const float ident_mat[16] =
959     {
960         1.0f, 0.0f, 0.0f, 0.0f,
961         0.0f, 1.0f, 0.0f, 0.0f,
962         0.0f, 0.0f, 1.0f, 0.0f,
963         0.0f, 0.0f, 0.0f, 1.0f
964     };
965     const float world_mat1[16] =
966     {
967         1.0f, 0.0f,  0.0f, 0.0f,
968         0.0f, 1.0f,  0.0f, 0.0f,
969         0.0f, 0.0f,  1.0f, 0.0f,
970         0.0f, 0.0f, -0.5f, 1.0f
971     };
972     const float world_mat2[16] =
973     {
974         1.0f, 0.0f, 0.0f, 0.0f,
975         0.0f, 1.0f, 0.0f, 0.0f,
976         0.0f, 0.0f, 1.0f, 0.0f,
977         0.0f, 0.0f, 1.0f, 1.0f
978     };
979     const float proj_mat[16] =
980     {
981         1.0f, 0.0f,  0.0f, 0.0f,
982         0.0f, 1.0f,  0.0f, 0.0f,
983         0.0f, 0.0f,  1.0f, 0.0f,
984         0.0f, 0.0f, -1.0f, 1.0f
985     };
986
987     const struct sVertex far_quad1[] =
988     {
989         {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
990         {-1.0f,  0.0f, 0.5f, 0xffff0000, 0xff000000},
991         { 0.0f,  0.0f, 0.5f, 0xffff0000, 0xff000000},
992         { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
993     };
994     const struct sVertex far_quad2[] =
995     {
996         {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
997         {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
998         { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
999         { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1000     };
1001
1002     memset(&caps, 0, sizeof(caps));
1003     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1004     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
1005     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1006     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1007
1008     /* Setup initial states: No lighting, fog on, fog color */
1009     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1010     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1011     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1012     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1013     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1014     ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1015
1016     /* First test: Both table fog and vertex fog off */
1017     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1018     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1019     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1020     ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1021
1022     /* Start = 0, end = 1. Should be default, but set them */
1023     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1024     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1025     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1026     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1027
1028     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1029     {
1030         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1031         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1032         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
1033         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1034                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1035                                                      sizeof(untransformed_1[0]));
1036         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1037
1038         /* That makes it use the Z value */
1039         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1040         ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
1041         /* Untransformed, vertex fog != none (or table fog != none):
1042          * Use the Z value as input into the equation
1043          */
1044         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1045                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1046                                                      sizeof(untransformed_2[0]));
1047         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1048
1049         /* transformed verts */
1050         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1051         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1052         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1053         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1054                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1055                                                      sizeof(transformed_1[0]));
1056         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1057
1058         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1059         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1060         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
1061          * equation
1062          */
1063         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1064                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
1065                                                      sizeof(transformed_2[0]));
1066         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1067
1068         hr = IDirect3DDevice9_EndScene(device);
1069         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1070     }
1071     else
1072     {
1073         ok(FALSE, "BeginScene failed\n");
1074     }
1075
1076     color = getPixelColor(device, 160, 360);
1077     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1078     color = getPixelColor(device, 160, 120);
1079     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1080     color = getPixelColor(device, 480, 120);
1081     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1082     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1083     {
1084         color = getPixelColor(device, 480, 360);
1085         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1086     }
1087     else
1088     {
1089         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1090          * The settings above result in no fogging with vertex fog
1091          */
1092         color = getPixelColor(device, 480, 120);
1093         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1094         trace("Info: Table fog not supported by this device\n");
1095     }
1096     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1097
1098     /* Now test the special case fogstart == fogend */
1099     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1100     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1101
1102     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1103     {
1104         start = 512;
1105         end = 512;
1106         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1107         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1108         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1109         ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1110
1111         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1112         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1113         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1114         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1115         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1116         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1117
1118         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1119          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1120          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1121          * The third transformed quad remains unfogged because the fogcoords are read from the specular
1122          * color and has fixed fogstart and fogend.
1123          */
1124         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1125                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1126                 sizeof(untransformed_1[0]));
1127         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1128         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1129                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1130                 sizeof(untransformed_2[0]));
1131         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1132
1133         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1134         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1135         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1136         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1137                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1138                 sizeof(transformed_1[0]));
1139         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1140
1141         hr = IDirect3DDevice9_EndScene(device);
1142         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1143     }
1144     else
1145     {
1146         ok(FALSE, "BeginScene failed\n");
1147     }
1148     color = getPixelColor(device, 160, 360);
1149     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1150     color = getPixelColor(device, 160, 120);
1151     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1152     color = getPixelColor(device, 480, 120);
1153     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1154     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1155
1156     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1157      * but without shaders it seems to work everywhere
1158      */
1159     end = 0.2;
1160     start = 0.8;
1161     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1162     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1163     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1164     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1165     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1166     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1167
1168     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1169      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1170      * so skip this for now
1171      */
1172     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1173         const char *mode = (i ? "table" : "vertex");
1174         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1175         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1176         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1177         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1178         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1179         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1180         hr = IDirect3DDevice9_BeginScene(device);
1181         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1182         if(SUCCEEDED(hr)) {
1183             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1184                                 4,  5,  6,  6,  7, 4,
1185                                 8,  9, 10, 10, 11, 8,
1186                             12, 13, 14, 14, 15, 12};
1187
1188             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1189                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1190                     sizeof(rev_fog_quads[0]));
1191             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1192
1193             hr = IDirect3DDevice9_EndScene(device);
1194             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1195         }
1196         color = getPixelColor(device, 160, 360);
1197         ok(color_match(color, 0x0000ff00, 1),
1198                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1199
1200         color = getPixelColor(device, 160, 120);
1201         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1202                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1203
1204         color = getPixelColor(device, 480, 120);
1205         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1206                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1207
1208         color = getPixelColor(device, 480, 360);
1209         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1210
1211         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1212
1213         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1214             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1215             break;
1216         }
1217     }
1218
1219     if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1220     {
1221         /* A simple fog + non-identity world matrix test */
1222         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat1);
1223         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
1224
1225         start = 0.0;
1226         end = 1.0;
1227         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1228         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1229         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1230         ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1231         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1232         ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1233         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1234         ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1235
1236         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1237         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
1238
1239         if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1240         {
1241             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1242             ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1243
1244             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1245                     2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1246             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1247
1248             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1249                     2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1250             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1251
1252             hr = IDirect3DDevice9_EndScene(device);
1253             ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1254         }
1255         else
1256         {
1257             ok(FALSE, "BeginScene failed\n");
1258         }
1259
1260         color = getPixelColor(device, 160, 360);
1261         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
1262                 "Unfogged quad has color %08x\n", color);
1263         color = getPixelColor(device, 160, 120);
1264         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1265                 "Fogged out quad has color %08x\n", color);
1266
1267         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1268
1269         /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
1270         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat2);
1271         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1272         hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)proj_mat);
1273         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1274
1275         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1276         ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1277
1278         if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1279         {
1280             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1281             ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1282
1283             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1284                     2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1285             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1286
1287             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1288                     2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1289             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1290
1291             hr = IDirect3DDevice9_EndScene(device);
1292             ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1293         }
1294         else
1295         {
1296             ok(FALSE, "BeginScene failed\n");
1297         }
1298
1299         color = getPixelColor(device, 160, 360);
1300         todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1301         color = getPixelColor(device, 160, 120);
1302         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1303                 "Fogged out quad has color %08x\n", color);
1304
1305         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1306
1307         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)ident_mat);
1308         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1309         hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)ident_mat);
1310         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1311     }
1312     else
1313     {
1314         skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1315     }
1316
1317     /* Test RANGEFOG vs FOGTABLEMODE */
1318     if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
1319             (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
1320     {
1321         struct sVertex untransformed_3[] =
1322         {
1323             {-1.0,-1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1324             {-1.0, 1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1325             { 1.0,-1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1326             { 1.0, 1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1327         };
1328
1329         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1330         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
1331         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1332         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
1333
1334         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
1335         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1336
1337         /* z=0.4999, set the fogstart to 0.5 and fogend slightly higher. If range fog
1338          * is not used, the fog coordinate will be equal to fogstart and the quad not
1339          * fogged. If range fog is used the fog coordinate will be slightly higher and
1340          * the fog coordinate will be > fogend, so we get a fully fogged quad. The fog
1341          * is calculated per vertex and interpolated, so even the center of the screen
1342          * where the difference doesn't matter will be fogged, but check the corners in
1343          * case a d3d/gl implementation decides to calculate the fog factor per fragment */
1344         start = 0.5f;
1345         end = 0.50001f;
1346         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1347         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1348         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1349         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1350
1351         /* Table fog: Range fog is not used */
1352         hr = IDirect3DDevice9_BeginScene(device);
1353         ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
1354         if (SUCCEEDED(hr))
1355         {
1356             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1357             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1358             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1359             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1360             hr = IDirect3DDevice9_EndScene(device);
1361             ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1362         }
1363         color = getPixelColor(device, 10, 10);
1364         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1365         color = getPixelColor(device, 630, 10);
1366         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1367         color = getPixelColor(device, 10, 470);
1368         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1369         color = getPixelColor(device, 630, 470);
1370         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1371
1372         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1373         ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1374
1375         /* Vertex fog: Rangefog is used */
1376         hr = IDirect3DDevice9_BeginScene(device);
1377         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP returned %#08x\n", hr);
1378         if (SUCCEEDED(hr))
1379         {
1380             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1381             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1382             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1383             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1384             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1385             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1386             hr = IDirect3DDevice9_EndScene(device);
1387             ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1388         }
1389         color = getPixelColor(device, 10, 10);
1390         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1391                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1392         color = getPixelColor(device, 630, 10);
1393         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1394                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1395         color = getPixelColor(device, 10, 470);
1396         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1397                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1398         color = getPixelColor(device, 630, 470);
1399         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1400                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1401
1402         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1403         ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1404
1405         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
1406         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1407     }
1408     else
1409     {
1410         skip("Range fog or table fog not supported, skipping range fog tests\n");
1411     }
1412
1413     /* Turn off the fog master switch to avoid confusing other tests */
1414     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1415     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1416     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1417     ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1418     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1419     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1420 }
1421
1422 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1423  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1424  * regardless of the actual addressing mode set. The way this test works is
1425  * that we sample in one of the corners of the cubemap with filtering enabled,
1426  * and check the interpolated color. There are essentially two reasonable
1427  * things an implementation can do: Either pick one of the faces and
1428  * interpolate the edge texel with itself (i.e., clamp within the face), or
1429  * interpolate between the edge texels of the three involved faces. It should
1430  * never involve the border color or the other side (texcoord wrapping) of a
1431  * face in the interpolation. */
1432 static void test_cube_wrap(IDirect3DDevice9 *device)
1433 {
1434     static const float quad[][6] = {
1435         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1436         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1437         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1438         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1439     };
1440
1441     static const D3DVERTEXELEMENT9 decl_elements[] = {
1442         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1443         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1444         D3DDECL_END()
1445     };
1446
1447     static const struct {
1448         D3DTEXTUREADDRESS mode;
1449         const char *name;
1450     } address_modes[] = {
1451         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1452         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1453         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1454         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1455         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1456     };
1457
1458     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1459     IDirect3DCubeTexture9 *texture = NULL;
1460     IDirect3DSurface9 *surface = NULL;
1461     IDirect3DSurface9 *face_surface;
1462     D3DLOCKED_RECT locked_rect;
1463     HRESULT hr;
1464     UINT x;
1465     INT y, face;
1466
1467     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1468     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1469     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1470     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1471
1472     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1473             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1474     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1475
1476     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1477             D3DPOOL_DEFAULT, &texture, NULL);
1478     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1479
1480     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1481     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1482
1483     for (y = 0; y < 128; ++y)
1484     {
1485         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1486         for (x = 0; x < 64; ++x)
1487         {
1488             *ptr++ = 0xff0000ff;
1489         }
1490         for (x = 64; x < 128; ++x)
1491         {
1492             *ptr++ = 0xffff0000;
1493         }
1494     }
1495
1496     hr = IDirect3DSurface9_UnlockRect(surface);
1497     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1498
1499     hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1500     ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1501
1502     hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1503     ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1504
1505     IDirect3DSurface9_Release(face_surface);
1506
1507     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1508     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1509
1510     for (y = 0; y < 128; ++y)
1511     {
1512         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1513         for (x = 0; x < 64; ++x)
1514         {
1515             *ptr++ = 0xffff0000;
1516         }
1517         for (x = 64; x < 128; ++x)
1518         {
1519             *ptr++ = 0xff0000ff;
1520         }
1521     }
1522
1523     hr = IDirect3DSurface9_UnlockRect(surface);
1524     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1525
1526     /* Create cube faces */
1527     for (face = 1; face < 6; ++face)
1528     {
1529         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1530         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1531
1532         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1533         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1534
1535         IDirect3DSurface9_Release(face_surface);
1536     }
1537
1538     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1539     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1540
1541     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1542     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1543     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1544     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1545     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1546     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1547
1548     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1549     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1550
1551     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1552     {
1553         DWORD color;
1554
1555         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1556         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1557         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1558         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1559
1560         hr = IDirect3DDevice9_BeginScene(device);
1561         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1562
1563         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1564         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1565
1566         hr = IDirect3DDevice9_EndScene(device);
1567         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1568
1569         color = getPixelColor(device, 320, 240);
1570         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1571                 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1572                 color, address_modes[x].name);
1573
1574         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1575         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1576
1577         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1578         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1579     }
1580
1581     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1582     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1583
1584     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1585     IDirect3DCubeTexture9_Release(texture);
1586     IDirect3DSurface9_Release(surface);
1587 }
1588
1589 static void offscreen_test(IDirect3DDevice9 *device)
1590 {
1591     HRESULT hr;
1592     IDirect3DTexture9 *offscreenTexture = NULL;
1593     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1594     DWORD color;
1595
1596     static const float quad[][5] = {
1597         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1598         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1599         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1600         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1601     };
1602
1603     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1604     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1605
1606     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1607     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1608     if(!offscreenTexture) {
1609         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1610         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1611         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1612         if(!offscreenTexture) {
1613             skip("Cannot create an offscreen render target\n");
1614             goto out;
1615         }
1616     }
1617
1618     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1619     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1620     if(!backbuffer) {
1621         goto out;
1622     }
1623
1624     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1625     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1626     if(!offscreen) {
1627         goto out;
1628     }
1629
1630     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1631     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1632
1633     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1634     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1635     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1636     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1637     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1638     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1639     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1640     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1641     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1642     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1643
1644     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1645         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1646         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1647         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1648         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1649
1650         /* Draw without textures - Should result in a white quad */
1651         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1652         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1653
1654         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1655         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1656         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1657         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1658
1659         /* This time with the texture */
1660         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1661         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1662
1663         IDirect3DDevice9_EndScene(device);
1664     }
1665
1666     /* Center quad - should be white */
1667     color = getPixelColor(device, 320, 240);
1668     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1669     /* Some quad in the cleared part of the texture */
1670     color = getPixelColor(device, 170, 240);
1671     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1672     /* Part of the originally cleared back buffer */
1673     color = getPixelColor(device, 10, 10);
1674     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1675     if(0) {
1676         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1677          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1678          * the offscreen rendering mode this test would succeed or fail
1679          */
1680         color = getPixelColor(device, 10, 470);
1681         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1682     }
1683
1684     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1685
1686 out:
1687     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1688     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1689
1690     /* restore things */
1691     if (backbuffer)
1692     {
1693         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1694         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1695         IDirect3DSurface9_Release(backbuffer);
1696     }
1697     if(offscreenTexture) {
1698         IDirect3DTexture9_Release(offscreenTexture);
1699     }
1700     if(offscreen) {
1701         IDirect3DSurface9_Release(offscreen);
1702     }
1703 }
1704
1705 /* This test tests fog in combination with shaders.
1706  * What's tested: linear fog (vertex and table) with pixel shader
1707  *                linear table fog with non foggy vertex shader
1708  *                vertex fog with foggy vertex shader, non-linear
1709  *                fog with shader, non-linear fog with foggy shader,
1710  *                linear table fog with foggy shader
1711  */
1712 static void fog_with_shader_test(IDirect3DDevice9 *device)
1713 {
1714     HRESULT hr;
1715     DWORD color;
1716     union {
1717         float f;
1718         DWORD i;
1719     } start, end;
1720     unsigned int i, j;
1721
1722     /* basic vertex shader without fog computation ("non foggy") */
1723     static const DWORD vertex_shader_code1[] =
1724     {
1725         0xfffe0101,                                                             /* vs_1_1                       */
1726         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1727         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1728         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1729         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1730         0x0000ffff
1731     };
1732     /* basic vertex shader with reversed fog computation ("foggy") */
1733     static const DWORD vertex_shader_code2[] =
1734     {
1735         0xfffe0101,                                                             /* vs_1_1                        */
1736         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1737         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1738         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1739         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1740         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1741         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1742         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1743         0x0000ffff
1744     };
1745     /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
1746     static const DWORD vertex_shader_code3[] =
1747     {
1748         0xfffe0200,                                                             /* vs_2_0                        */
1749         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1750         0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1751         0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1752         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1753         0x02000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1754         0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1755         0x03000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1756         0x0000ffff
1757     };
1758     /* basic pixel shader */
1759     static const DWORD pixel_shader_code[] =
1760     {
1761         0xffff0101,                                                             /* ps_1_1     */
1762         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0 */
1763         0x0000ffff
1764     };
1765     static const DWORD pixel_shader_code2[] =
1766     {
1767         0xffff0200,                                                             /* ps_2_0     */
1768         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0 */
1769         0x02000001, 0x800f0800, 0x90e40000,                                     /* mov oC0, v0 */
1770         0x0000ffff
1771     };
1772
1773     static struct vertex quad[] = {
1774         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1775         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1776         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1777         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1778     };
1779
1780     static const D3DVERTEXELEMENT9 decl_elements[] = {
1781         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1782         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1783         D3DDECL_END()
1784     };
1785
1786     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1787     IDirect3DVertexShader9      *vertex_shader[4]   = {NULL, NULL, NULL, NULL};
1788     IDirect3DPixelShader9       *pixel_shader[3]    = {NULL, NULL, NULL};
1789
1790     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1791     static const struct test_data_t {
1792         int vshader;
1793         int pshader;
1794         D3DFOGMODE vfog;
1795         D3DFOGMODE tfog;
1796         unsigned int color[11];
1797     } test_data[] = {
1798         /* only pixel shader: */
1799         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1800         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1801         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1802         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1803         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1804         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1805         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1806         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1807         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1808         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1809         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1810         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1811         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1812         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1813         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1814
1815         /* vertex shader */
1816         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1817         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1818          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1819         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1820         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1821         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1822         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1823         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1824         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1825
1826         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1827         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1828         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1829         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1830         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1831         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1832
1833         /* vertex shader and pixel shader */
1834         /* The next 4 tests would read the fog coord output, but it isn't available.
1835          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1836          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1837          * These tests should be disabled if some other hardware behaves differently
1838          */
1839         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1840         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1841         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1842         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1843         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1844         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1845         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1846         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1847         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1848         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1849         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1850         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1851
1852         /* These use the Z coordinate with linear table fog */
1853         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1854         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1855         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1856         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1857         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1858         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1859         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1860         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1861         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1862         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1863         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1864         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1865
1866         /* Non-linear table fog without fog coord */
1867         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1868         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1869         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1870         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1871         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1872         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1873
1874         /* These tests fail on older Nvidia drivers */
1875         /* foggy vertex shader */
1876         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1877         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1878          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1879         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1880         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1881          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1882         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1883         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1884          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1885         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1886         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1887          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1888
1889         {3, 0, D3DFOG_NONE, D3DFOG_NONE,
1890         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1891          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1892         {3, 0, D3DFOG_EXP, D3DFOG_NONE,
1893         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1894          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1895         {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
1896         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1897          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1898         {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1899         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1900          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1901
1902         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1903          * all using the fixed fog-coord linear fog
1904          */
1905         /* vs_1_1 with ps_1_1 */
1906         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1907         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1908          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1909         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1910         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1911          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1912         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1913         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1914          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1915         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1916         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1917          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1918
1919         /* vs_2_0 with ps_1_1 */
1920         {3, 1, D3DFOG_NONE, D3DFOG_NONE,
1921         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1922          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1923         {3, 1, D3DFOG_EXP, D3DFOG_NONE,
1924         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1925          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1926         {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
1927         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1928          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1929         {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1930         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1931          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1932
1933         /* vs_1_1 with ps_2_0 */
1934         {2, 2, D3DFOG_NONE, D3DFOG_NONE,
1935         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1936          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1937         {2, 2, D3DFOG_EXP, D3DFOG_NONE,
1938         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1939          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1940         {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
1941         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1942          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1943         {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
1944         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1945          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1946
1947         /* vs_2_0 with ps_2_0 */
1948         {3, 2, D3DFOG_NONE, D3DFOG_NONE,
1949         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1950          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1951         {3, 2, D3DFOG_EXP, D3DFOG_NONE,
1952         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1953          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1954         {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
1955         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1956          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1957         {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
1958         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1959          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1960
1961         /* These use table fog. Here the shader-provided fog coordinate is
1962          * ignored and the z coordinate used instead
1963          */
1964         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1965         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1966         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1967         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1968         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1969         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1970         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1971         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1972         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1973     };
1974
1975     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1976     start.f=0.1f;
1977     end.f=0.9f;
1978
1979     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1980     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1981     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1982     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1983     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
1984     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1985     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1986     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1987     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
1988     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1989     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1990     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1991
1992     /* Setup initial states: No lighting, fog on, fog color */
1993     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1994     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1995     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1996     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1997     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1998     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1999     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2000     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2001
2002     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2003     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
2004     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2005     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
2006
2007     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
2008     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
2009     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
2010     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
2011     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
2012
2013     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
2014     {
2015         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
2016         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2017         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
2018         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2019         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
2020         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2021         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
2022         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2023
2024         for(j=0; j < 11; j++)
2025         {
2026             /* Don't use the whole zrange to prevent rounding errors */
2027             quad[0].z = 0.001f + (float)j / 10.02f;
2028             quad[1].z = 0.001f + (float)j / 10.02f;
2029             quad[2].z = 0.001f + (float)j / 10.02f;
2030             quad[3].z = 0.001f + (float)j / 10.02f;
2031
2032             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2033             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2034
2035             hr = IDirect3DDevice9_BeginScene(device);
2036             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
2037
2038             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2039             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2040
2041             hr = IDirect3DDevice9_EndScene(device);
2042             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
2043
2044             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
2045             color = getPixelColor(device, 128, 240);
2046             ok(color_match(color, test_data[i].color[j], 13),
2047                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
2048                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
2049
2050             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2051         }
2052     }
2053
2054     /* reset states */
2055     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2056     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2057     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2058     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2059     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2060     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2061     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
2062     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
2063
2064     IDirect3DVertexShader9_Release(vertex_shader[1]);
2065     IDirect3DVertexShader9_Release(vertex_shader[2]);
2066     IDirect3DVertexShader9_Release(vertex_shader[3]);
2067     IDirect3DPixelShader9_Release(pixel_shader[1]);
2068     IDirect3DPixelShader9_Release(pixel_shader[2]);
2069     IDirect3DVertexDeclaration9_Release(vertex_declaration);
2070 }
2071
2072 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
2073     unsigned int i, x, y;
2074     HRESULT hr;
2075     IDirect3DTexture9 *texture[2] = {NULL, NULL};
2076     D3DLOCKED_RECT locked_rect;
2077
2078     /* Generate the textures */
2079     for(i=0; i<2; i++)
2080     {
2081         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
2082                                             D3DPOOL_MANAGED, &texture[i], NULL);
2083         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
2084
2085         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
2086         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2087         for (y = 0; y < 128; ++y)
2088         {
2089             if(i)
2090             { /* Set up black texture with 2x2 texel white spot in the middle */
2091                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2092                 for (x = 0; x < 128; ++x)
2093                 {
2094                     if(y>62 && y<66 && x>62 && x<66)
2095                         *ptr++ = 0xffffffff;
2096                     else
2097                         *ptr++ = 0xff000000;
2098                 }
2099             }
2100             else
2101             { /* Set up a displacement map which points away from the center parallel to the closest axis.
2102                * (if multiplied with bumpenvmat)
2103               */
2104                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2105                 for (x = 0; x < 128; ++x)
2106                 {
2107                     if(abs(x-64)>abs(y-64))
2108                     {
2109                         if(x < 64)
2110                             *ptr++ = 0xc000;
2111                         else
2112                             *ptr++ = 0x4000;
2113                     }
2114                     else
2115                     {
2116                         if(y < 64)
2117                             *ptr++ = 0x0040;
2118                         else
2119                             *ptr++ = 0x00c0;
2120                     }
2121                 }
2122             }
2123         }
2124         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2125         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2126
2127         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2128         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2129
2130         /* Disable texture filtering */
2131         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2132         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2133         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2134         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2135
2136         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2137         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2138         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2139         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2140     }
2141 }
2142
2143 /* test the behavior of the texbem instruction
2144  * with normal 2D and projective 2D textures
2145  */
2146 static void texbem_test(IDirect3DDevice9 *device)
2147 {
2148     HRESULT hr;
2149     DWORD color;
2150     int i;
2151
2152     static const DWORD pixel_shader_code[] = {
2153         0xffff0101,                         /* ps_1_1*/
2154         0x00000042, 0xb00f0000,             /* tex t0*/
2155         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2156         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
2157         0x0000ffff
2158     };
2159     static const DWORD double_texbem_code[] =  {
2160         0xffff0103,                                         /* ps_1_3           */
2161         0x00000042, 0xb00f0000,                             /* tex t0           */
2162         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
2163         0x00000042, 0xb00f0002,                             /* tex t2           */
2164         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
2165         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
2166         0x0000ffff                                          /* end              */
2167     };
2168
2169
2170     static const float quad[][7] = {
2171         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
2172         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
2173         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
2174         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
2175     };
2176     static const float quad_proj[][9] = {
2177         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
2178         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
2179         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
2180         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
2181     };
2182
2183     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
2184         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2185         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2186         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2187         D3DDECL_END()
2188     },{
2189         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2190         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2191         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2192         D3DDECL_END()
2193     } };
2194
2195     /* use asymmetric matrix to test loading */
2196     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
2197
2198     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2199     IDirect3DPixelShader9       *pixel_shader       = NULL;
2200     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
2201     D3DLOCKED_RECT locked_rect;
2202
2203     generate_bumpmap_textures(device);
2204
2205     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2206     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2207     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2208     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2209     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
2210
2211     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2212     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2213
2214     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2215     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2216
2217     for(i=0; i<2; i++)
2218     {
2219         if(i)
2220         {
2221             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
2222             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2223         }
2224
2225         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
2226         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2227         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2228         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2229
2230         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
2231         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2232         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2233         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2234
2235         hr = IDirect3DDevice9_BeginScene(device);
2236         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2237
2238         if(!i)
2239             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2240         else
2241             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
2242         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2243
2244         hr = IDirect3DDevice9_EndScene(device);
2245         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2246
2247         color = getPixelColor(device, 320-32, 240);
2248         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2249         color = getPixelColor(device, 320+32, 240);
2250         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2251         color = getPixelColor(device, 320, 240-32);
2252         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2253         color = getPixelColor(device, 320, 240+32);
2254         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2255
2256         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2257         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2258
2259         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2260         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2261         IDirect3DPixelShader9_Release(pixel_shader);
2262
2263         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2264         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2265         IDirect3DVertexDeclaration9_Release(vertex_declaration);
2266     }
2267
2268     /* clean up */
2269     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2270     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2271
2272     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2273     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2274
2275     for(i=0; i<2; i++)
2276     {
2277         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
2278         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
2279         IDirect3DTexture9_Release(texture); /* For the GetTexture */
2280         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2281         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2282         IDirect3DTexture9_Release(texture);
2283     }
2284
2285     /* Test double texbem */
2286     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
2287     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2288     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
2289     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2290     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
2291     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2292     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
2293     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2294
2295     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
2296     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2297     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
2298     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
2299
2300     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2301     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2302
2303     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
2304     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2305     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
2306     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
2307     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
2308     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2309
2310     {
2311         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
2312 #define tex  0x00ff0000
2313 #define tex1 0x0000ff00
2314 #define origin 0x000000ff
2315         static const DWORD pixel_data[] = {
2316             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2317             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2318             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2319             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2320             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
2321             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2322             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2323             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2324         };
2325 #undef tex1
2326 #undef tex2
2327 #undef origin
2328
2329         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
2330         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2331         for(i = 0; i < 8; i++) {
2332             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
2333         }
2334         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
2335         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2336     }
2337
2338     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2339     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2340     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
2341     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2342     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
2343     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2344     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2345     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2346     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2347     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2348     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2349     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2350
2351     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
2352     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
2353     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2354     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2355     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2356     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2357     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2358     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2359     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2360     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2361
2362     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2363     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2364     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2365     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2366     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2367     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2368     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2369     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2370     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2371     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2372
2373     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2374     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2375     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2376     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2377     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2378     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2379     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2380     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2381     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2382     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2383     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2384     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2385     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2386     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2387     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2388     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2389
2390     hr = IDirect3DDevice9_BeginScene(device);
2391     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2392     if(SUCCEEDED(hr)) {
2393         static const float double_quad[] = {
2394             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2395              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2396             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2397              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2398         };
2399
2400         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2401         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2402         hr = IDirect3DDevice9_EndScene(device);
2403         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2404     }
2405     color = getPixelColor(device, 320, 240);
2406     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2407
2408     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2409     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2410     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2411     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2412     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2413     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2414     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2415     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2416     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2417     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2418
2419     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2420     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2421
2422     IDirect3DPixelShader9_Release(pixel_shader);
2423     IDirect3DTexture9_Release(texture);
2424     IDirect3DTexture9_Release(texture1);
2425     IDirect3DTexture9_Release(texture2);
2426 }
2427
2428 static void z_range_test(IDirect3DDevice9 *device)
2429 {
2430     const struct vertex quad[] =
2431     {
2432         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2433         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2434         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2435         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2436     };
2437     const struct vertex quad2[] =
2438     {
2439         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2440         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2441         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2442         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2443     };
2444
2445     const struct tvertex quad3[] =
2446     {
2447         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2448         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2449         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2450         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2451     };
2452     const struct tvertex quad4[] =
2453     {
2454         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2455         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2456         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2457         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2458     };
2459     HRESULT hr;
2460     DWORD color;
2461     IDirect3DVertexShader9 *shader;
2462     IDirect3DVertexDeclaration9 *decl;
2463     D3DCAPS9 caps;
2464     const DWORD shader_code[] = {
2465         0xfffe0101,                                     /* vs_1_1           */
2466         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2467         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2468         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2469         0x0000ffff                                      /* end              */
2470     };
2471     static const D3DVERTEXELEMENT9 decl_elements[] = {
2472         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2473         D3DDECL_END()
2474     };
2475
2476     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2477
2478     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2479      * then call Present. Then clear the color buffer to make sure it has some defined content
2480      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2481      * by the depth value.
2482      */
2483     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2484     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2485     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2486     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2487     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2488     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2489
2490     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2491     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2492     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2493     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2494     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2495     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2496     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2497     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2498     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2499     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2500
2501     hr = IDirect3DDevice9_BeginScene(device);
2502     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2503     if(hr == D3D_OK)
2504     {
2505         /* Test the untransformed vertex path */
2506         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2507         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2508         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2509         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2510         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2511         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2512
2513         /* Test the transformed vertex path */
2514         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2515         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2516
2517         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2518         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2519         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2520         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2521         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2522         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2523
2524         hr = IDirect3DDevice9_EndScene(device);
2525         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2526     }
2527
2528     /* Do not test the exact corner pixels, but go pretty close to them */
2529
2530     /* Clipped because z > 1.0 */
2531     color = getPixelColor(device, 28, 238);
2532     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2533     color = getPixelColor(device, 28, 241);
2534     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2535     {
2536         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2537     }
2538     else
2539     {
2540         ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2541     }
2542
2543     /* Not clipped, > z buffer clear value(0.75) */
2544     color = getPixelColor(device, 31, 238);
2545     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2546     color = getPixelColor(device, 31, 241);
2547     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2548     color = getPixelColor(device, 100, 238);
2549     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2550     color = getPixelColor(device, 100, 241);
2551     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2552
2553     /* Not clipped, < z buffer clear value */
2554     color = getPixelColor(device, 104, 238);
2555     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2556     color = getPixelColor(device, 104, 241);
2557     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2558     color = getPixelColor(device, 318, 238);
2559     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2560     color = getPixelColor(device, 318, 241);
2561     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2562
2563     /* Clipped because z < 0.0 */
2564     color = getPixelColor(device, 321, 238);
2565     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2566     color = getPixelColor(device, 321, 241);
2567     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2568     {
2569         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2570     }
2571     else
2572     {
2573         ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2574     }
2575
2576     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2577     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2578
2579     /* Test the shader path */
2580     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2581         skip("Vertex shaders not supported\n");
2582         goto out;
2583     }
2584     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2585     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2586     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2587     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2588
2589     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2590
2591     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2592     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2593     hr = IDirect3DDevice9_SetVertexShader(device, shader);
2594     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2595
2596     hr = IDirect3DDevice9_BeginScene(device);
2597     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2598     if(hr == D3D_OK)
2599     {
2600         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2601         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2602         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2603         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2604         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2605         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2606         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2607         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2608         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2609         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2610
2611         hr = IDirect3DDevice9_EndScene(device);
2612         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2613     }
2614
2615     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2616     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2617     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2618     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2619
2620     IDirect3DVertexDeclaration9_Release(decl);
2621     IDirect3DVertexShader9_Release(shader);
2622
2623     /* Z < 1.0 */
2624     color = getPixelColor(device, 28, 238);
2625     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2626
2627     /* 1.0 < z < 0.75 */
2628     color = getPixelColor(device, 31, 238);
2629     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2630     color = getPixelColor(device, 100, 238);
2631     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2632
2633     /* 0.75 < z < 0.0 */
2634     color = getPixelColor(device, 104, 238);
2635     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2636     color = getPixelColor(device, 318, 238);
2637     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2638
2639     /* 0.0 < z */
2640     color = getPixelColor(device, 321, 238);
2641     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2642
2643     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2644     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2645
2646     out:
2647     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2648     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2649     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2650     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2651     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2652     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2653 }
2654
2655 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2656 {
2657     D3DSURFACE_DESC desc;
2658     D3DLOCKED_RECT l;
2659     HRESULT hr;
2660     unsigned int x, y;
2661     DWORD *mem;
2662
2663     memset(&desc, 0, sizeof(desc));
2664     memset(&l, 0, sizeof(l));
2665     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2666     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2667     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2668     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2669     if(FAILED(hr)) return;
2670
2671     for(y = 0; y < desc.Height; y++)
2672     {
2673         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2674         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2675         {
2676             mem[x] = color;
2677         }
2678     }
2679     hr = IDirect3DSurface9_UnlockRect(surface);
2680     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2681 }
2682
2683 /* This tests a variety of possible StretchRect() situations */
2684 static void stretchrect_test(IDirect3DDevice9 *device)
2685 {
2686     HRESULT hr;
2687     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2688     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2689     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2690     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2691     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2692     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2693     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2694     IDirect3DSurface9 *orig_rt = NULL;
2695     IDirect3DSurface9 *backbuffer = NULL;
2696     DWORD color;
2697
2698     RECT src_rect64 = {0, 0, 64, 64};
2699     RECT src_rect64_flipy = {0, 64, 64, 0};
2700     RECT dst_rect64 = {0, 0, 64, 64};
2701     RECT dst_rect64_flipy = {0, 64, 64, 0};
2702
2703     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2704     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2705     if(!orig_rt) {
2706         goto out;
2707     }
2708
2709     /* Create our temporary surfaces in system memory */
2710     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2711     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2712     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2713     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2714
2715     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2716     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2717     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2718     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2719     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2720     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2721     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2722
2723     /* Create render target surfaces */
2724     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2725     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2726     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2727     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2728     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2729     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2730     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2731     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2732
2733     /* Create render target textures */
2734     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2735     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2736     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2737     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2738     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2739     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2740     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2741     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2742     if (tex_rt32) {
2743         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2744         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2745     }
2746     if (tex_rt64) {
2747         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2748         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2749     }
2750     if (tex_rt_dest64) {
2751         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2752         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2753     }
2754     if (tex_rt_dest640_480) {
2755         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2756         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2757     }
2758
2759     /* Create regular textures in D3DPOOL_DEFAULT */
2760     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2761     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2762     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2763     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2764     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2765     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2766     if (tex32) {
2767         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2768         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2769     }
2770     if (tex64) {
2771         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2772         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2773     }
2774     if (tex_dest64) {
2775         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2776         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2777     }
2778
2779     /*********************************************************************
2780      * Tests for when the source parameter is an offscreen plain surface *
2781      *********************************************************************/
2782
2783     /* Fill the offscreen 64x64 surface with green */
2784     if (surf_offscreen64)
2785         fill_surface(surf_offscreen64, 0xff00ff00);
2786
2787     /* offscreenplain ==> offscreenplain, same size */
2788     if(surf_offscreen64 && surf_offscreen_dest64) {
2789         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2790         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2791
2792         if (hr == D3D_OK) {
2793             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2794             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2795         }
2796
2797         /* Blit without scaling */
2798         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2799         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2800
2801         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2802         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2803         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2804
2805         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2806         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2807         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2808     }
2809
2810     /* offscreenplain ==> rendertarget texture, same size */
2811     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2812         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2813         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2814
2815         /* We can't lock rendertarget textures, so copy to our temp surface first */
2816         if (hr == D3D_OK) {
2817             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2818             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2819         }
2820
2821         if (hr == D3D_OK) {
2822             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2823             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2824         }
2825
2826         /* Blit without scaling */
2827         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2828         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2829
2830         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2831         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2832         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2833
2834         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2835         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2836         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2837     }
2838
2839     /* offscreenplain ==> rendertarget surface, same size */
2840     if(surf_offscreen64 && surf_rt_dest64) {
2841         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2842         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2843
2844         if (hr == D3D_OK) {
2845             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2846             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2847         }
2848
2849         /* Blit without scaling */
2850         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2851         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2852
2853         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2854         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2855         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2856
2857         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2858         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2859         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2860     }
2861
2862     /* offscreenplain ==> texture, same size (should fail) */
2863     if(surf_offscreen64 && surf_tex_dest64) {
2864         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2865         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2866     }
2867
2868     /* Fill the smaller offscreen surface with red */
2869     fill_surface(surf_offscreen32, 0xffff0000);
2870
2871     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2872     if(surf_offscreen32 && surf_offscreen64) {
2873         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2874         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2875     }
2876
2877     /* offscreenplain ==> rendertarget texture, scaling */
2878     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2879         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2880         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2881
2882         /* We can't lock rendertarget textures, so copy to our temp surface first */
2883         if (hr == D3D_OK) {
2884             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2885             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2886         }
2887
2888         if (hr == D3D_OK) {
2889             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2890             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2891         }
2892     }
2893
2894     /* offscreenplain ==> rendertarget surface, scaling */
2895     if(surf_offscreen32 && surf_rt_dest64) {
2896         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2897         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2898
2899         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2900         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2901     }
2902
2903     /* offscreenplain ==> texture, scaling (should fail) */
2904     if(surf_offscreen32 && surf_tex_dest64) {
2905         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2906         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2907     }
2908
2909     /************************************************************
2910      * Tests for when the source parameter is a regular texture *
2911      ************************************************************/
2912
2913     /* Fill the surface of the regular texture with blue */
2914     if (surf_tex64 && surf_temp64) {
2915         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2916         fill_surface(surf_temp64, 0xff0000ff);
2917         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2918         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2919     }
2920
2921     /* texture ==> offscreenplain, same size */
2922     if(surf_tex64 && surf_offscreen64) {
2923         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2924         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2925     }
2926
2927     /* texture ==> rendertarget texture, same size */
2928     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2929         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2930         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2931
2932         /* We can't lock rendertarget textures, so copy to our temp surface first */
2933         if (hr == D3D_OK) {
2934             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2935             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2936         }
2937
2938         if (hr == D3D_OK) {
2939             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2940             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2941         }
2942
2943         /* Blit without scaling */
2944         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2945         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2946
2947         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2948         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2949         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2950
2951         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2952         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2953         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2954     }
2955
2956     /* texture ==> rendertarget surface, same size */
2957     if(surf_tex64 && surf_rt_dest64) {
2958         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2959         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2960
2961         if (hr == D3D_OK) {
2962             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2963             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2964         }
2965
2966         /* Blit without scaling */
2967         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2968         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2969
2970         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2971         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2972         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2973
2974         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2975         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2976         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2977     }
2978
2979     /* texture ==> texture, same size (should fail) */
2980     if(surf_tex64 && surf_tex_dest64) {
2981         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2982         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2983     }
2984
2985     /* Fill the surface of the smaller regular texture with red */
2986     if (surf_tex32 && surf_temp32) {
2987         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2988         fill_surface(surf_temp32, 0xffff0000);
2989         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2990         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2991     }
2992
2993     /* texture ==> offscreenplain, scaling (should fail) */
2994     if(surf_tex32 && surf_offscreen64) {
2995         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2996         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2997     }
2998
2999     /* texture ==> rendertarget texture, scaling */
3000     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
3001         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
3002         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3003
3004         /* We can't lock rendertarget textures, so copy to our temp surface first */
3005         if (hr == D3D_OK) {
3006             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3007             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3008         }
3009
3010         if (hr == D3D_OK) {
3011             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3012             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3013         }
3014     }
3015
3016     /* texture ==> rendertarget surface, scaling */
3017     if(surf_tex32 && surf_rt_dest64) {
3018         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
3019         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3020
3021         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3022         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3023     }
3024
3025     /* texture ==> texture, scaling (should fail) */
3026     if(surf_tex32 && surf_tex_dest64) {
3027         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
3028         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3029     }
3030
3031     /*****************************************************************
3032      * Tests for when the source parameter is a rendertarget texture *
3033      *****************************************************************/
3034
3035     /* Fill the surface of the rendertarget texture with white */
3036     if (surf_tex_rt64 && surf_temp64) {
3037         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
3038         fill_surface(surf_temp64, 0xffffffff);
3039         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
3040         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3041     }
3042
3043     /* rendertarget texture ==> offscreenplain, same size */
3044     if(surf_tex_rt64 && surf_offscreen64) {
3045         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
3046         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3047     }
3048
3049     /* rendertarget texture ==> rendertarget texture, same size */
3050     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3051         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3052         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3053
3054         /* We can't lock rendertarget textures, so copy to our temp surface first */
3055         if (hr == D3D_OK) {
3056             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3057             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3058         }
3059
3060         if (hr == D3D_OK) {
3061             color = getPixelColorFromSurface(surf_temp64, 32, 32);
3062             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
3063         }
3064
3065         /* Blit without scaling */
3066         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3067         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3068
3069         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3070         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3071         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3072
3073         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3074         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3075         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3076     }
3077
3078     /* rendertarget texture ==> rendertarget surface, same size */
3079     if(surf_tex_rt64 && surf_rt_dest64) {
3080         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
3081         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3082
3083         if (hr == D3D_OK) {
3084             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3085             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
3086         }
3087
3088         /* Blit without scaling */
3089         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3090         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3091
3092         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3093         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
3094         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3095
3096         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3097         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3098         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3099     }
3100
3101     /* rendertarget texture ==> texture, same size (should fail) */
3102     if(surf_tex_rt64 && surf_tex_dest64) {
3103         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
3104         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3105     }
3106
3107     /* Fill the surface of the smaller rendertarget texture with red */
3108     if (surf_tex_rt32 && surf_temp32) {
3109         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
3110         fill_surface(surf_temp32, 0xffff0000);
3111         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3112         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3113     }
3114
3115     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
3116     if(surf_tex_rt32 && surf_offscreen64) {
3117         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
3118         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3119     }
3120
3121     /* rendertarget texture ==> rendertarget texture, scaling */
3122     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3123         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3124         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3125
3126         /* We can't lock rendertarget textures, so copy to our temp surface first */
3127         if (hr == D3D_OK) {
3128             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3129             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3130         }
3131
3132         if (hr == D3D_OK) {
3133             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3134             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3135         }
3136     }
3137
3138     /* rendertarget texture ==> rendertarget surface, scaling */
3139     if(surf_tex_rt32 && surf_rt_dest64) {
3140         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
3141         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3142
3143         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3144         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3145     }
3146
3147     /* rendertarget texture ==> texture, scaling (should fail) */
3148     if(surf_tex_rt32 && surf_tex_dest64) {
3149         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
3150         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3151     }
3152
3153     /*****************************************************************
3154      * Tests for when the source parameter is a rendertarget surface *
3155      *****************************************************************/
3156
3157     /* Fill the surface of the rendertarget surface with black */
3158     if (surf_rt64)
3159         fill_surface(surf_rt64, 0xff000000);
3160
3161     /* rendertarget texture ==> offscreenplain, same size */
3162     if(surf_rt64 && surf_offscreen64) {
3163         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
3164         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3165     }
3166
3167     /* rendertarget surface ==> rendertarget texture, same size */
3168     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3169         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3170         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3171
3172         /* We can't lock rendertarget textures, so copy to our temp surface first */
3173         if (hr == D3D_OK) {
3174             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3175             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3176         }
3177
3178         if (hr == D3D_OK) {
3179             color = getPixelColorFromSurface(surf_temp64, 32, 32);
3180             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3181         }
3182
3183         /* Blit without scaling */
3184         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3185         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3186
3187         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3188         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3189         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3190
3191         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3192         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3193         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3194     }
3195
3196     /* rendertarget surface ==> rendertarget surface, same size */
3197     if(surf_rt64 && surf_rt_dest64) {
3198         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
3199         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3200
3201         if (hr == D3D_OK) {
3202             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3203             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3204         }
3205
3206         /* Blit without scaling */
3207         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3208         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3209
3210         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3211         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
3212         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3213
3214         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3215         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3216         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3217     }
3218
3219     /* rendertarget surface ==> texture, same size (should fail) */
3220     if(surf_rt64 && surf_tex_dest64) {
3221         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
3222         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3223     }
3224
3225     /* Fill the surface of the smaller rendertarget texture with red */
3226     if (surf_rt32)
3227         fill_surface(surf_rt32, 0xffff0000);
3228
3229     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
3230     if(surf_rt32 && surf_offscreen64) {
3231         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
3232         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3233     }
3234
3235     /* rendertarget surface ==> rendertarget texture, scaling */
3236     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3237         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3238         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3239
3240         /* We can't lock rendertarget textures, so copy to our temp surface first */
3241         if (hr == D3D_OK) {
3242             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3243             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3244         }
3245
3246         if (hr == D3D_OK) {
3247             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3248             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3249         }
3250     }
3251
3252     /* rendertarget surface ==> rendertarget surface, scaling */
3253     if(surf_rt32 && surf_rt_dest64) {
3254         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
3255         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3256
3257         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3258         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3259     }
3260
3261     /* rendertarget surface ==> texture, scaling (should fail) */
3262     if(surf_rt32 && surf_tex_dest64) {
3263         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
3264         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3265     }
3266
3267     /* backbuffer ==> surface tests (no scaling) */
3268     if(backbuffer && surf_tex_rt_dest640_480)
3269     {
3270         RECT src_rect = {0, 0, 640, 480};
3271         RECT src_rect_flipy = {0, 480, 640, 0};
3272         RECT dst_rect = {0, 0, 640, 480};
3273         RECT dst_rect_flipy = {0, 480, 640, 0};
3274
3275         /* Blit with NULL rectangles */
3276         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
3277         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
3278
3279         /* Blit without scaling */
3280         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
3281         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3282
3283         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3284         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
3285         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3286
3287         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3288         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
3289         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3290     }
3291
3292     /* TODO: Test format conversions */
3293
3294
3295 out:
3296     /* Clean up */
3297     if (backbuffer)
3298         IDirect3DSurface9_Release(backbuffer);
3299     if (surf_rt32)
3300         IDirect3DSurface9_Release(surf_rt32);
3301     if (surf_rt64)
3302         IDirect3DSurface9_Release(surf_rt64);
3303     if (surf_rt_dest64)
3304         IDirect3DSurface9_Release(surf_rt_dest64);
3305     if (surf_temp32)
3306         IDirect3DSurface9_Release(surf_temp32);
3307     if (surf_temp64)
3308         IDirect3DSurface9_Release(surf_temp64);
3309     if (surf_offscreen32)
3310         IDirect3DSurface9_Release(surf_offscreen32);
3311     if (surf_offscreen64)
3312         IDirect3DSurface9_Release(surf_offscreen64);
3313     if (surf_offscreen_dest64)
3314         IDirect3DSurface9_Release(surf_offscreen_dest64);
3315
3316     if (tex_rt32) {
3317         if (surf_tex_rt32)
3318             IDirect3DSurface9_Release(surf_tex_rt32);
3319         IDirect3DTexture9_Release(tex_rt32);
3320     }
3321     if (tex_rt64) {
3322         if (surf_tex_rt64)
3323             IDirect3DSurface9_Release(surf_tex_rt64);
3324         IDirect3DTexture9_Release(tex_rt64);
3325     }
3326     if (tex_rt_dest64) {
3327         if (surf_tex_rt_dest64)
3328             IDirect3DSurface9_Release(surf_tex_rt_dest64);
3329         IDirect3DTexture9_Release(tex_rt_dest64);
3330     }
3331     if (tex_rt_dest640_480) {
3332         if (surf_tex_rt_dest640_480)
3333             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
3334         IDirect3DTexture9_Release(tex_rt_dest640_480);
3335     }
3336     if (tex32) {
3337         if (surf_tex32)
3338             IDirect3DSurface9_Release(surf_tex32);
3339         IDirect3DTexture9_Release(tex32);
3340     }
3341     if (tex64) {
3342         if (surf_tex64)
3343             IDirect3DSurface9_Release(surf_tex64);
3344         IDirect3DTexture9_Release(tex64);
3345     }
3346     if (tex_dest64) {
3347         if (surf_tex_dest64)
3348             IDirect3DSurface9_Release(surf_tex_dest64);
3349         IDirect3DTexture9_Release(tex_dest64);
3350     }
3351
3352     if (orig_rt) {
3353         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3354         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3355         IDirect3DSurface9_Release(orig_rt);
3356     }
3357 }
3358
3359 static void maxmip_test(IDirect3DDevice9 *device)
3360 {
3361     IDirect3DTexture9 *texture = NULL;
3362     IDirect3DSurface9 *surface = NULL;
3363     HRESULT hr;
3364     DWORD color;
3365     static const struct
3366     {
3367         struct
3368         {
3369             float x, y, z;
3370             float s, t;
3371         }
3372         v[4];
3373     }
3374     quads[] =
3375     {
3376         {{
3377             {-1.0, -1.0,  0.0,  0.0,  0.0},
3378             {-1.0,  0.0,  0.0,  0.0,  1.0},
3379             { 0.0, -1.0,  0.0,  1.0,  0.0},
3380             { 0.0,  0.0,  0.0,  1.0,  1.0},
3381         }},
3382         {{
3383             { 0.0, -1.0,  0.0,  0.0,  0.0},
3384             { 0.0,  0.0,  0.0,  0.0,  1.0},
3385             { 1.0, -1.0,  0.0,  1.0,  0.0},
3386             { 1.0,  0.0,  0.0,  1.0,  1.0},
3387         }},
3388         {{
3389             { 0.0,  0.0,  0.0,  0.0,  0.0},
3390             { 0.0,  1.0,  0.0,  0.0,  1.0},
3391             { 1.0,  0.0,  0.0,  1.0,  0.0},
3392             { 1.0,  1.0,  0.0,  1.0,  1.0},
3393         }},
3394         {{
3395             {-1.0,  0.0,  0.0,  0.0,  0.0},
3396             {-1.0,  1.0,  0.0,  0.0,  1.0},
3397             { 0.0,  0.0,  0.0,  1.0,  0.0},
3398             { 0.0,  1.0,  0.0,  1.0,  1.0},
3399         }},
3400     };
3401
3402     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3403                                         &texture, NULL);
3404     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3405     if(!texture)
3406     {
3407         skip("Failed to create test texture\n");
3408         return;
3409     }
3410
3411     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3412     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3413     fill_surface(surface, 0xffff0000);
3414     IDirect3DSurface9_Release(surface);
3415     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3416     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3417     fill_surface(surface, 0xff00ff00);
3418     IDirect3DSurface9_Release(surface);
3419     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3420     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3421     fill_surface(surface, 0xff0000ff);
3422     IDirect3DSurface9_Release(surface);
3423
3424     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3425     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3426     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3427     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3428
3429     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3430     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3431
3432     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3433     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3434
3435     hr = IDirect3DDevice9_BeginScene(device);
3436     if(SUCCEEDED(hr))
3437     {
3438         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3439         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3440         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3441         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3442
3443         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3444         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3445         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3446         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3447
3448         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3449         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3450         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3451         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3452
3453         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3454         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3455         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3456         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3457         hr = IDirect3DDevice9_EndScene(device);
3458         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3459     }
3460
3461     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3462     color = getPixelColor(device, 160, 360);
3463     ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3464     color = getPixelColor(device, 480, 360);
3465     ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3466     color = getPixelColor(device, 480, 120);
3467     ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3468     color = getPixelColor(device, 160, 120);
3469     ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3470     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3471     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3472
3473     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3474     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3475
3476     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3477     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3478
3479     hr = IDirect3DDevice9_BeginScene(device);
3480     if(SUCCEEDED(hr))
3481     {
3482         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3483         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3484         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3485         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3486
3487         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3488         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3489         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3490         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3491
3492         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3493         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3494         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3495         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3496
3497         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3498         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3499         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3500         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3501         hr = IDirect3DDevice9_EndScene(device);
3502         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3503     }
3504
3505     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3506      * level 3 (> levels in texture) samples from the highest level in the
3507      * texture (level 2). */
3508     color = getPixelColor(device, 160, 360);
3509     ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3510     color = getPixelColor(device, 480, 360);
3511     ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3512     color = getPixelColor(device, 480, 120);
3513     ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3514     color = getPixelColor(device, 160, 120);
3515     ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3516     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3517     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3518
3519     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3520     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3521
3522     hr = IDirect3DDevice9_BeginScene(device);
3523     if(SUCCEEDED(hr))
3524     {
3525         DWORD ret;
3526
3527         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3528         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3529         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3530         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3531         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3532         ret = IDirect3DTexture9_SetLOD(texture, 1);
3533         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3534         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3535         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3536
3537         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3538         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3539         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3540         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3541         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3542         ret = IDirect3DTexture9_SetLOD(texture, 2);
3543         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3544         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3545         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3546
3547         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3548         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3549         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3550         ret = IDirect3DTexture9_SetLOD(texture, 1);
3551         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3552         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3553         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3554
3555         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3556         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3557         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3558         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3559         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3560         ret = IDirect3DTexture9_SetLOD(texture, 1);
3561         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3562         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3563         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3564         hr = IDirect3DDevice9_EndScene(device);
3565         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3566     }
3567
3568     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3569      * level 3 (> levels in texture) samples from the highest level in the
3570      * texture (level 2). */
3571     color = getPixelColor(device, 160, 360);
3572     ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3573     color = getPixelColor(device, 480, 360);
3574     ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3575     color = getPixelColor(device, 480, 120);
3576     ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3577     color = getPixelColor(device, 160, 120);
3578     ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3579
3580     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3581     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3582
3583     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3584     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3585     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3586     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3587     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3588     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3589     IDirect3DTexture9_Release(texture);
3590 }
3591
3592 static void release_buffer_test(IDirect3DDevice9 *device)
3593 {
3594     IDirect3DVertexBuffer9 *vb = NULL;
3595     IDirect3DIndexBuffer9 *ib = NULL;
3596     HRESULT hr;
3597     BYTE *data;
3598     LONG ref;
3599
3600     static const struct vertex quad[] = {
3601         {-1.0,      -1.0,       0.1,        0xffff0000},
3602         {-1.0,       1.0,       0.1,        0xffff0000},
3603         { 1.0,       1.0,       0.1,        0xffff0000},
3604
3605         {-1.0,      -1.0,       0.1,        0xff00ff00},
3606         {-1.0,       1.0,       0.1,        0xff00ff00},
3607         { 1.0,       1.0,       0.1,        0xff00ff00}
3608     };
3609     short indices[] = {3, 4, 5};
3610
3611     /* Index and vertex buffers should always be creatable */
3612     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3613                                               D3DPOOL_MANAGED, &vb, NULL);
3614     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3615     if(!vb) {
3616         skip("Failed to create a vertex buffer\n");
3617         return;
3618     }
3619     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3620     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3621     if(!ib) {
3622         skip("Failed to create an index buffer\n");
3623         return;
3624     }
3625
3626     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3627     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3628     memcpy(data, quad, sizeof(quad));
3629     hr = IDirect3DVertexBuffer9_Unlock(vb);
3630     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3631
3632     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3633     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3634     memcpy(data, indices, sizeof(indices));
3635     hr = IDirect3DIndexBuffer9_Unlock(ib);
3636     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3637
3638     hr = IDirect3DDevice9_SetIndices(device, ib);
3639     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3640     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3641     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3642     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3643     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3644
3645     /* Now destroy the bound index buffer and draw again */
3646     ref = IDirect3DIndexBuffer9_Release(ib);
3647     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3648
3649     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3650     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3651
3652     hr = IDirect3DDevice9_BeginScene(device);
3653     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3654     if(SUCCEEDED(hr))
3655     {
3656         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3657          * making assumptions about the indices or vertices
3658          */
3659         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3660         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3661         hr = IDirect3DDevice9_EndScene(device);
3662         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3663     }
3664
3665     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3666     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3667
3668     hr = IDirect3DDevice9_SetIndices(device, NULL);
3669     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3670     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3671     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3672
3673     /* Index buffer was already destroyed as part of the test */
3674     IDirect3DVertexBuffer9_Release(vb);
3675 }
3676
3677 static void float_texture_test(IDirect3DDevice9 *device)
3678 {
3679     IDirect3D9 *d3d = NULL;
3680     HRESULT hr;
3681     IDirect3DTexture9 *texture = NULL;
3682     D3DLOCKED_RECT lr;
3683     float *data;
3684     DWORD color;
3685     float quad[] = {
3686         -1.0,      -1.0,       0.1,     0.0,    0.0,
3687         -1.0,       1.0,       0.1,     0.0,    1.0,
3688          1.0,      -1.0,       0.1,     1.0,    0.0,
3689          1.0,       1.0,       0.1,     1.0,    1.0,
3690     };
3691
3692     memset(&lr, 0, sizeof(lr));
3693     IDirect3DDevice9_GetDirect3D(device, &d3d);
3694     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3695                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3696         skip("D3DFMT_R32F textures not supported\n");
3697         goto out;
3698     }
3699
3700     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3701                                         D3DPOOL_MANAGED, &texture, NULL);
3702     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3703     if(!texture) {
3704         skip("Failed to create R32F texture\n");
3705         goto out;
3706     }
3707
3708     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3709     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3710     data = lr.pBits;
3711     *data = 0.0;
3712     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3713     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3714
3715     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3716     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3717
3718     hr = IDirect3DDevice9_BeginScene(device);
3719     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3720     if(SUCCEEDED(hr))
3721     {
3722         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3723         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3724
3725         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3726         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3727
3728         hr = IDirect3DDevice9_EndScene(device);
3729         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3730     }
3731     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3732     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3733
3734     color = getPixelColor(device, 240, 320);
3735     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3736
3737     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3738     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3739
3740 out:
3741     if(texture) IDirect3DTexture9_Release(texture);
3742     IDirect3D9_Release(d3d);
3743 }
3744
3745 static void g16r16_texture_test(IDirect3DDevice9 *device)
3746 {
3747     IDirect3D9 *d3d = NULL;
3748     HRESULT hr;
3749     IDirect3DTexture9 *texture = NULL;
3750     D3DLOCKED_RECT lr;
3751     DWORD *data;
3752     DWORD color;
3753     float quad[] = {
3754        -1.0,      -1.0,       0.1,     0.0,    0.0,
3755        -1.0,       1.0,       0.1,     0.0,    1.0,
3756         1.0,      -1.0,       0.1,     1.0,    0.0,
3757         1.0,       1.0,       0.1,     1.0,    1.0,
3758     };
3759
3760     memset(&lr, 0, sizeof(lr));
3761     IDirect3DDevice9_GetDirect3D(device, &d3d);
3762     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3763        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3764            skip("D3DFMT_G16R16 textures not supported\n");
3765            goto out;
3766     }
3767
3768     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3769                                         D3DPOOL_MANAGED, &texture, NULL);
3770     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3771     if(!texture) {
3772         skip("Failed to create D3DFMT_G16R16 texture\n");
3773         goto out;
3774     }
3775
3776     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3777     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3778     data = lr.pBits;
3779     *data = 0x0f00f000;
3780     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3781     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3782
3783     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3784     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3785
3786     hr = IDirect3DDevice9_BeginScene(device);
3787     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3788     if(SUCCEEDED(hr))
3789     {
3790         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3791         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3792
3793         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3794         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3795
3796         hr = IDirect3DDevice9_EndScene(device);
3797         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3798     }
3799     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3800     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3801
3802     color = getPixelColor(device, 240, 320);
3803     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3804        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3805
3806     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3807     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3808
3809 out:
3810     if(texture) IDirect3DTexture9_Release(texture);
3811     IDirect3D9_Release(d3d);
3812 }
3813
3814 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
3815 {
3816     LONG x_coords[2][2] =
3817     {
3818         {r.left - 1, r.left + 1},
3819         {r.right + 1, r.right - 1},
3820     };
3821     LONG y_coords[2][2] =
3822     {
3823         {r.top - 1, r.top + 1},
3824         {r.bottom + 1, r.bottom - 1}
3825     };
3826     unsigned int i, j, x_side, y_side;
3827
3828     for (i = 0; i < 2; ++i)
3829     {
3830         for (j = 0; j < 2; ++j)
3831         {
3832             for (x_side = 0; x_side < 2; ++x_side)
3833             {
3834                 for (y_side = 0; y_side < 2; ++y_side)
3835                 {
3836                     unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
3837                     DWORD color;
3838                     DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
3839
3840                     color = getPixelColor(device, x, y);
3841                     ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
3842                             message, x, y, color, expected);
3843                 }
3844             }
3845         }
3846     }
3847 }
3848
3849 struct projected_textures_test_run
3850 {
3851     const char *message;
3852     DWORD flags;
3853     IDirect3DVertexDeclaration9 *decl;
3854     BOOL vs, ps;
3855     RECT rect;
3856 };
3857
3858 static void projected_textures_test(IDirect3DDevice9 *device,
3859         struct projected_textures_test_run tests[4])
3860 {
3861     unsigned int i;
3862
3863     static const DWORD vertex_shader[] =
3864     {
3865         0xfffe0101,                                     /* vs_1_1           */
3866         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
3867         0x0000001f, 0x80000005, 0x900f0001,             /* dcl_texcoord0 v1 */
3868         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
3869         0x00000001, 0xe00f0000, 0x90e40001,             /* mov oT0, v1      */
3870         0x0000ffff                                      /* end              */
3871     };
3872     static const DWORD pixel_shader[] =
3873     {
3874         0xffff0103,                                     /* ps_1_3           */
3875         0x00000042, 0xb00f0000,                         /* tex t0           */
3876         0x00000001, 0x800f0000, 0xb0e40000,             /* mov r0, t0       */
3877         0x0000ffff                                      /* end              */
3878     };
3879     IDirect3DVertexShader9 *vs = NULL;
3880     IDirect3DPixelShader9 *ps = NULL;
3881     IDirect3D9 *d3d;
3882     D3DCAPS9 caps;
3883     HRESULT hr;
3884
3885     IDirect3DDevice9_GetDirect3D(device, &d3d);
3886     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3887     ok(SUCCEEDED(hr), "GetDeviceCaps failed (%08x)\n", hr);
3888     IDirect3D9_Release(d3d);
3889
3890     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
3891     {
3892         hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
3893         ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
3894     }
3895     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 3))
3896     {
3897         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
3898         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3899     }
3900
3901     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
3902     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3903
3904     hr = IDirect3DDevice9_BeginScene(device);
3905     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3906     if (FAILED(hr))
3907         return;
3908
3909     for (i = 0; i < 4; ++i)
3910     {
3911         DWORD value = 0xdeadbeef;
3912         static const float proj_quads[] =
3913         {
3914             -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3915              0.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3916             -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3917              0.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3918
3919              0.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3920              1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3921              0.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3922              1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3923
3924             -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3925              0.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3926             -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3927              0.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3928
3929              0.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3930              1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3931              0.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3932              1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3933         };
3934
3935         if (tests[i].vs)
3936         {
3937             if (!vs)
3938             {
3939                 skip("Vertex shaders not supported, skipping\n");
3940                 continue;
3941             }
3942             hr = IDirect3DDevice9_SetVertexShader(device, vs);
3943         }
3944         else
3945             hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3946         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
3947         if (tests[i].ps)
3948         {
3949             if (!ps)
3950             {
3951                 skip("Pixel shaders not supported, skipping\n");
3952                 continue;
3953             }
3954             hr = IDirect3DDevice9_SetPixelShader(device, ps);
3955         }
3956         else
3957             hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3958         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3959
3960         hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
3961         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3962
3963         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
3964         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3965         hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
3966         ok(SUCCEEDED(hr) && value == tests[i].flags,
3967                 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
3968
3969         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
3970                 &proj_quads[i * 4 * 7], 7 * sizeof(float));
3971         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3972     }
3973
3974     hr = IDirect3DDevice9_EndScene(device);
3975     ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3976
3977     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3978     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3979     if (vs) IDirect3DVertexShader9_Release(vs);
3980     if (ps) IDirect3DPixelShader9_Release(ps);
3981
3982     for (i = 0; i < 4; ++i)
3983     {
3984         if ((!tests[i].vs || vs) && (!tests[i].ps || ps))
3985             check_rect(device, tests[i].rect, tests[i].message);
3986     }
3987
3988     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3989     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3990 }
3991
3992 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3993 {
3994     HRESULT hr;
3995     IDirect3D9 *d3d;
3996     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3997     D3DCAPS9 caps;
3998     IDirect3DTexture9 *texture = NULL;
3999     IDirect3DVolumeTexture9 *volume = NULL;
4000     unsigned int x, y, z;
4001     D3DLOCKED_RECT lr;
4002     D3DLOCKED_BOX lb;
4003     DWORD color;
4004     UINT w, h;
4005     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
4006     float identity[16] = {1.0, 0.0, 0.0, 0.0,
4007                            0.0, 1.0, 0.0, 0.0,
4008                            0.0, 0.0, 1.0, 0.0,
4009                            0.0, 0.0, 0.0, 1.0};
4010     static const D3DVERTEXELEMENT9 decl_elements[] = {
4011         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4012         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4013         D3DDECL_END()
4014     };
4015     static const D3DVERTEXELEMENT9 decl_elements2[] = {
4016         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4017         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4018         D3DDECL_END()
4019     };
4020     static const D3DVERTEXELEMENT9 decl_elements3[] = {
4021         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4022         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4023         D3DDECL_END()
4024     };
4025     static const D3DVERTEXELEMENT9 decl_elements4[] = {
4026         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4027         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4028         D3DDECL_END()
4029     };
4030     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
4031                                                  0x00, 0xff, 0x00, 0x00,
4032                                                  0x00, 0x00, 0x00, 0x00,
4033                                                  0x00, 0x00, 0x00, 0x00};
4034
4035     memset(&lr, 0, sizeof(lr));
4036     memset(&lb, 0, sizeof(lb));
4037     IDirect3DDevice9_GetDirect3D(device, &d3d);
4038     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
4039                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
4040         fmt = D3DFMT_A16B16G16R16;
4041     }
4042     IDirect3D9_Release(d3d);
4043
4044     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4045     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4046     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4047     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4048     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
4049     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4050     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
4051     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4052     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
4053     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
4054     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
4055     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
4056     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
4057     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
4058     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4059     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
4060     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
4061     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
4062     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
4063     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
4064     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
4065     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
4066     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4067     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLOROP) returned %08x\n", hr);
4068     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4069     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLORARG1) returned %08x\n", hr);
4070     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4071     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
4072     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4073     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4074
4075     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4076     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
4077     w = min(1024, caps.MaxTextureWidth);
4078     h = min(1024, caps.MaxTextureHeight);
4079     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
4080                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
4081     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4082     if(!texture) {
4083         skip("Failed to create the test texture\n");
4084         return;
4085     }
4086
4087     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
4088      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
4089      * 1.0 in red and green for the x and y coords
4090      */
4091     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4092     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
4093     for(y = 0; y < h; y++) {
4094         for(x = 0; x < w; x++) {
4095             double r_f = (double) y / (double) h;
4096             double g_f = (double) x / (double) w;
4097             if(fmt == D3DFMT_A16B16G16R16) {
4098                 unsigned short r, g;
4099                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
4100                 r = (unsigned short) (r_f * 65536.0);
4101                 g = (unsigned short) (g_f * 65536.0);
4102                 dst[0] = r;
4103                 dst[1] = g;
4104                 dst[2] = 0;
4105                 dst[3] = 65535;
4106             } else {
4107                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
4108                 unsigned char r = (unsigned char) (r_f * 255.0);
4109                 unsigned char g = (unsigned char) (g_f * 255.0);
4110                 dst[0] = 0;
4111                 dst[1] = g;
4112                 dst[2] = r;
4113                 dst[3] = 255;
4114             }
4115         }
4116     }
4117     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4118     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4119     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4120     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4121
4122     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4123     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4124     hr = IDirect3DDevice9_BeginScene(device);
4125     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4126     if(SUCCEEDED(hr))
4127     {
4128         float quad1[] = {
4129             -1.0,      -1.0,       0.1,     1.0,    1.0,
4130             -1.0,       0.0,       0.1,     1.0,    1.0,
4131              0.0,      -1.0,       0.1,     1.0,    1.0,
4132              0.0,       0.0,       0.1,     1.0,    1.0,
4133         };
4134         float quad2[] = {
4135             -1.0,       0.0,       0.1,     1.0,    1.0,
4136             -1.0,       1.0,       0.1,     1.0,    1.0,
4137              0.0,       0.0,       0.1,     1.0,    1.0,
4138              0.0,       1.0,       0.1,     1.0,    1.0,
4139         };
4140         float quad3[] = {
4141              0.0,       0.0,       0.1,     0.5,    0.5,
4142              0.0,       1.0,       0.1,     0.5,    0.5,
4143              1.0,       0.0,       0.1,     0.5,    0.5,
4144              1.0,       1.0,       0.1,     0.5,    0.5,
4145         };
4146         float quad4[] = {
4147              320,       480,       0.1,     1.0,    0.0,    1.0,
4148              320,       240,       0.1,     1.0,    0.0,    1.0,
4149              640,       480,       0.1,     1.0,    0.0,    1.0,
4150              640,       240,       0.1,     1.0,    0.0,    1.0,
4151         };
4152         float mat[16] = {0.0, 0.0, 0.0, 0.0,
4153                           0.0, 0.0, 0.0, 0.0,
4154                           0.0, 0.0, 0.0, 0.0,
4155                           0.0, 0.0, 0.0, 0.0};
4156
4157         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4158         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4159         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4160         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4161         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4162
4163         /* What happens with transforms enabled? */
4164         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4165         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4166         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4167         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4168
4169         /* What happens if 4 coords are used, but only 2 given ?*/
4170         mat[8] = 1.0;
4171         mat[13] = 1.0;
4172         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4173         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4174         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4175         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4176         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4177         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4178
4179         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4180          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4181          * due to the coords in the vertices. (turns out red, indeed)
4182          */
4183         memset(mat, 0, sizeof(mat));
4184         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4185         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4186         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4187         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4188         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4189         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4190         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4191         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4192
4193         hr = IDirect3DDevice9_EndScene(device);
4194         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4195     }
4196     color = getPixelColor(device, 160, 360);
4197     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
4198     color = getPixelColor(device, 160, 120);
4199     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4200     color = getPixelColor(device, 480, 120);
4201     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
4202     color = getPixelColor(device, 480, 360);
4203     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
4204     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4205     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4206
4207     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4208     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4209
4210     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4211     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4212     hr = IDirect3DDevice9_BeginScene(device);
4213     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4214     if(SUCCEEDED(hr))
4215     {
4216         float quad1[] = {
4217             -1.0,      -1.0,       0.1,     0.8,    0.2,
4218             -1.0,       0.0,       0.1,     0.8,    0.2,
4219              0.0,      -1.0,       0.1,     0.8,    0.2,
4220              0.0,       0.0,       0.1,     0.8,    0.2,
4221         };
4222         float quad2[] = {
4223             -1.0,       0.0,       0.1,     0.5,    1.0,
4224             -1.0,       1.0,       0.1,     0.5,    1.0,
4225              0.0,       0.0,       0.1,     0.5,    1.0,
4226              0.0,       1.0,       0.1,     0.5,    1.0,
4227         };
4228         float quad3[] = {
4229              0.0,       0.0,       0.1,     0.5,    1.0,
4230              0.0,       1.0,       0.1,     0.5,    1.0,
4231              1.0,       0.0,       0.1,     0.5,    1.0,
4232              1.0,       1.0,       0.1,     0.5,    1.0,
4233         };
4234         float quad4[] = {
4235              0.0,      -1.0,       0.1,     0.8,    0.2,
4236              0.0,       0.0,       0.1,     0.8,    0.2,
4237              1.0,      -1.0,       0.1,     0.8,    0.2,
4238              1.0,       0.0,       0.1,     0.8,    0.2,
4239         };
4240         float mat[16] = {0.0, 0.0, 0.0, 0.0,
4241                           0.0, 0.0, 0.0, 0.0,
4242                           0.0, 1.0, 0.0, 0.0,
4243                           0.0, 0.0, 0.0, 0.0};
4244
4245         /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
4246         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4247         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4248         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4249         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4250
4251         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4252         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4253
4254         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
4255          * it behaves like COUNT2 because normal textures require 2 coords. */
4256         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4257         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4258         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
4259         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4260
4261         /* Just to be sure, the same as quad2 above */
4262         memset(mat, 0, sizeof(mat));
4263         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4264         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4265         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4266         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4267         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4268         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4269
4270         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
4271          * used? And what happens to the first? */
4272         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4273         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4274         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4275         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4276
4277         hr = IDirect3DDevice9_EndScene(device);
4278         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4279     }
4280     color = getPixelColor(device, 160, 360);
4281     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
4282     color = getPixelColor(device, 160, 120);
4283     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4284     color = getPixelColor(device, 480, 120);
4285     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
4286        "quad 3 has color %08x, expected 0x00ff8000\n", color);
4287     color = getPixelColor(device, 480, 360);
4288     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
4289        "quad 4 has color %08x, expected 0x0033cc00\n", color);
4290     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4291     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4292
4293     IDirect3DTexture9_Release(texture);
4294
4295     /* Test projected textures, without any fancy matrices */
4296     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
4297     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4298     if (SUCCEEDED(hr))
4299     {
4300         struct projected_textures_test_run projected_tests_1[4] =
4301         {
4302             {
4303                 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
4304                 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
4305                 decl3,
4306                 FALSE, TRUE,
4307                 {120, 300, 240, 390},
4308             },
4309             {
4310                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
4311                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4312                 decl3,
4313                 FALSE, TRUE,
4314                 {400, 360, 480, 420},
4315             },
4316             /* Try with some invalid values */
4317             {
4318                 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
4319                 0xffffffff,
4320                 decl3,
4321                 FALSE, TRUE,
4322                 {120, 60, 240, 150}
4323             },
4324             {
4325                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
4326                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4327                 decl4,
4328                 FALSE, TRUE,
4329                 {340, 210, 360, 225},
4330             }
4331         };
4332         struct projected_textures_test_run projected_tests_2[4] =
4333         {
4334             {
4335                 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
4336                 D3DTTFF_PROJECTED,
4337                 decl3,
4338                 FALSE, TRUE,
4339                 {120, 300, 240, 390},
4340             },
4341             {
4342                 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
4343                 D3DTTFF_PROJECTED,
4344                 decl,
4345                 FALSE, TRUE,
4346                 {400, 360, 480, 420},
4347             },
4348             {
4349                 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
4350                 0xffffffff,
4351                 decl,
4352                 FALSE, TRUE,
4353                 {80, 120, 160, 180},
4354             },
4355             {
4356                 "D3DTTFF_COUNT1 (draws non-projected) - top right",
4357                 D3DTTFF_COUNT1,
4358                 decl4,
4359                 FALSE, TRUE,
4360                 {340, 210, 360, 225},
4361             }
4362         };
4363         struct projected_textures_test_run projected_tests_3[4] =
4364         {
4365             {
4366                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
4367                 D3DTTFF_PROJECTED,
4368                 decl3,
4369                 TRUE, FALSE,
4370                 {120, 300, 240, 390},
4371             },
4372             {
4373                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
4374                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4375                 decl3,
4376                 TRUE, TRUE,
4377                 {440, 300, 560, 390},
4378             },
4379             {
4380                 "0xffffffff (like COUNT4 | PROJECTED) - top left",
4381                 0xffffffff,
4382                 decl3,
4383                 TRUE, TRUE,
4384                 {120, 60, 240, 150},
4385             },
4386             {
4387                 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
4388                 D3DTTFF_PROJECTED,
4389                 decl3,
4390                 FALSE, FALSE,
4391                 {440, 60, 560, 150},
4392             },
4393         };
4394
4395         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4396         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4397
4398         hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4399         ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4400         for(x = 0; x < 4; x++) {
4401             memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
4402         }
4403         hr = IDirect3DTexture9_UnlockRect(texture, 0);
4404         ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4405         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4406         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4407
4408         projected_textures_test(device, projected_tests_1);
4409         projected_textures_test(device, projected_tests_2);
4410         projected_textures_test(device, projected_tests_3);
4411
4412         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4413         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4414         IDirect3DTexture9_Release(texture);
4415     }
4416
4417     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
4418     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4419     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
4420      * Thus watch out if sampling from texels between 0 and 1.
4421      */
4422     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
4423     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
4424        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
4425     if(!volume) {
4426         skip("Failed to create a volume texture\n");
4427         goto out;
4428     }
4429
4430     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
4431     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
4432     for(z = 0; z < 32; z++) {
4433         for(y = 0; y < 32; y++) {
4434             for(x = 0; x < 32; x++) {
4435                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
4436                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
4437                 float r_f = (float) x / 31.0;
4438                 float g_f = (float) y / 31.0;
4439                 float b_f = (float) z / 31.0;
4440
4441                 if(fmt == D3DFMT_A16B16G16R16) {
4442                     unsigned short *mem_s = mem;
4443                     mem_s[0]  = r_f * 65535.0;
4444                     mem_s[1]  = g_f * 65535.0;
4445                     mem_s[2]  = b_f * 65535.0;
4446                     mem_s[3]  = 65535;
4447                 } else {
4448                     unsigned char *mem_c = mem;
4449                     mem_c[0]  = b_f * 255.0;
4450                     mem_c[1]  = g_f * 255.0;
4451                     mem_c[2]  = r_f * 255.0;
4452                     mem_c[3]  = 255;
4453                 }
4454             }
4455         }
4456     }
4457     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
4458     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4459
4460     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
4461     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4462
4463     hr = IDirect3DDevice9_BeginScene(device);
4464     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4465     if(SUCCEEDED(hr))
4466     {
4467         float quad1[] = {
4468             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4469             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4470              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4471              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4472         };
4473         float quad2[] = {
4474             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4475             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
4476              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4477              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
4478         };
4479         float quad3[] = {
4480              0.0,       0.0,       0.1,     0.0,    0.0,
4481              0.0,       1.0,       0.1,     0.0,    0.0,
4482              1.0,       0.0,       0.1,     0.0,    0.0,
4483              1.0,       1.0,       0.1,     0.0,    0.0
4484         };
4485         float quad4[] = {
4486              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4487              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4488              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4489              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
4490         };
4491         float mat[16] = {1.0, 0.0, 0.0, 0.0,
4492                          0.0, 0.0, 1.0, 0.0,
4493                          0.0, 1.0, 0.0, 0.0,
4494                          0.0, 0.0, 0.0, 1.0};
4495         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4496         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4497
4498         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
4499          * values
4500          */
4501         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4502         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4503         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4504         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4505         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4506         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4507
4508         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
4509          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
4510          * otherwise the w will be missing(blue).
4511          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
4512          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
4513         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4514         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4515         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4516         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4517
4518         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
4519         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4520         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4521         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4522         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4523         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4524         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4525         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4526         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4527
4528         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4529          * disable. ATI extends it up to the amount of values needed for the volume texture
4530          */
4531         memset(mat, 0, sizeof(mat));
4532         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4533         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4534         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4535         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4536         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4537         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4538         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4539         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4540
4541         hr = IDirect3DDevice9_EndScene(device);
4542         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4543     }
4544
4545     color = getPixelColor(device, 160, 360);
4546     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4547     color = getPixelColor(device, 160, 120);
4548     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4549        "quad 2 has color %08x, expected 0x00ffff00\n", color);
4550     color = getPixelColor(device, 480, 120);
4551     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4552     color = getPixelColor(device, 480, 360);
4553     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4554
4555     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4556     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4557
4558     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4559     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4560     hr = IDirect3DDevice9_BeginScene(device);
4561     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4562     if(SUCCEEDED(hr))
4563     {
4564         float quad1[] = {
4565             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4566             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4567              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4568              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4569         };
4570         float quad2[] = {
4571             -1.0,       0.0,       0.1,
4572             -1.0,       1.0,       0.1,
4573              0.0,       0.0,       0.1,
4574              0.0,       1.0,       0.1,
4575         };
4576         float quad3[] = {
4577              0.0,       0.0,       0.1,     1.0,
4578              0.0,       1.0,       0.1,     1.0,
4579              1.0,       0.0,       0.1,     1.0,
4580              1.0,       1.0,       0.1,     1.0
4581         };
4582         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4583                            0.0, 0.0, 0.0, 0.0,
4584                            0.0, 0.0, 0.0, 0.0,
4585                            0.0, 1.0, 0.0, 0.0};
4586         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4587                            1.0, 0.0, 0.0, 0.0,
4588                            0.0, 1.0, 0.0, 0.0,
4589                            0.0, 0.0, 1.0, 0.0};
4590         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4591         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4592
4593         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4594          * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4595          * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4596          * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4597          * 4th *input* coordinate.
4598          */
4599         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4600         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4601         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4602         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4603         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4604         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4605
4606         /* None passed */
4607         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4608         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4609         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4610         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4611         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4612         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4613
4614         /* 4 used, 1 passed */
4615         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4616         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4617         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4618         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4619         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4620         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4621
4622         hr = IDirect3DDevice9_EndScene(device);
4623         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4624     }
4625     color = getPixelColor(device, 160, 360);
4626     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4627     color = getPixelColor(device, 160, 120);
4628     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4629     color = getPixelColor(device, 480, 120);
4630     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4631     /* Quad4: unused */
4632
4633     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4634     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4635
4636     IDirect3DVolumeTexture9_Release(volume);
4637
4638     out:
4639     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4640     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4641     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4642     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4643     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4644     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4645     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4646     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4647     IDirect3DVertexDeclaration9_Release(decl);
4648     IDirect3DVertexDeclaration9_Release(decl2);
4649     IDirect3DVertexDeclaration9_Release(decl3);
4650     IDirect3DVertexDeclaration9_Release(decl4);
4651 }
4652
4653 static void texdepth_test(IDirect3DDevice9 *device)
4654 {
4655     IDirect3DPixelShader9 *shader;
4656     HRESULT hr;
4657     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4658     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4659     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4660     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4661     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4662     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4663     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4664     DWORD shader_code[] = {
4665         0xffff0104,                                                                 /* ps_1_4               */
4666         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4667         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4668         0x0000fffd,                                                                 /* phase                */
4669         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4670         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4671         0x0000ffff                                                                  /* end                  */
4672     };
4673     DWORD color;
4674     float vertex[] = {
4675        -1.0,   -1.0,    0.0,
4676         1.0,   -1.0,    1.0,
4677        -1.0,    1.0,    0.0,
4678         1.0,    1.0,    1.0
4679     };
4680
4681     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4682     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4683
4684     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4685     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4686     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4687     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4688     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4689     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4690     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4691     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4692     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4693     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4694
4695     /* Fill the depth buffer with a gradient */
4696     hr = IDirect3DDevice9_BeginScene(device);
4697     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4698     if(SUCCEEDED(hr))
4699     {
4700         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4701         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4702         hr = IDirect3DDevice9_EndScene(device);
4703         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4704     }
4705
4706     /* Now perform the actual tests. Same geometry, but with the shader */
4707     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4708     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4709     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4710     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4711     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4712     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4713
4714     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4715     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4716     hr = IDirect3DDevice9_BeginScene(device);
4717     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4718     if(SUCCEEDED(hr))
4719     {
4720         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4721         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4722
4723         hr = IDirect3DDevice9_EndScene(device);
4724         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4725     }
4726
4727     color = getPixelColor(device, 158, 240);
4728     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4729     color = getPixelColor(device, 162, 240);
4730     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4731
4732     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4733     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4734
4735     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4736     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4737
4738     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4739     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4740     hr = IDirect3DDevice9_BeginScene(device);
4741     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4742     if(SUCCEEDED(hr))
4743     {
4744         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4745         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4746
4747         hr = IDirect3DDevice9_EndScene(device);
4748         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4749     }
4750
4751     color = getPixelColor(device, 318, 240);
4752     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4753     color = getPixelColor(device, 322, 240);
4754     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4755
4756     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4757     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4758
4759     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4760     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4761
4762     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4763     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4764     hr = IDirect3DDevice9_BeginScene(device);
4765     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4766     if(SUCCEEDED(hr))
4767     {
4768         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4769         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4770
4771         hr = IDirect3DDevice9_EndScene(device);
4772         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4773     }
4774
4775     color = getPixelColor(device, 1, 240);
4776     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4777
4778     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4779     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4780
4781     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4782     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4783
4784     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4785     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4786     hr = IDirect3DDevice9_BeginScene(device);
4787     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4788     if(SUCCEEDED(hr))
4789     {
4790         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4791         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4792
4793         hr = IDirect3DDevice9_EndScene(device);
4794         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4795     }
4796     color = getPixelColor(device, 318, 240);
4797     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4798     color = getPixelColor(device, 322, 240);
4799     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4800
4801     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4802     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4803
4804     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4805     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4806
4807     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4808     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4809     hr = IDirect3DDevice9_BeginScene(device);
4810     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4811     if(SUCCEEDED(hr))
4812     {
4813         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4814         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4815
4816         hr = IDirect3DDevice9_EndScene(device);
4817         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4818     }
4819
4820     color = getPixelColor(device, 1, 240);
4821     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4822
4823     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4824     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4825
4826     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4827     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4828
4829     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4830     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4831     hr = IDirect3DDevice9_BeginScene(device);
4832     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4833     if(SUCCEEDED(hr))
4834     {
4835         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4836         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4837
4838         hr = IDirect3DDevice9_EndScene(device);
4839         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4840     }
4841
4842     color = getPixelColor(device, 638, 240);
4843     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4844
4845     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4846     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4847
4848     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4849     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4850
4851     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4852     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4853     hr = IDirect3DDevice9_BeginScene(device);
4854     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4855     if(SUCCEEDED(hr))
4856     {
4857         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4858         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4859
4860         hr = IDirect3DDevice9_EndScene(device);
4861         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4862     }
4863
4864     color = getPixelColor(device, 638, 240);
4865     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4866
4867     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4868     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4869
4870     /* Cleanup */
4871     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4872     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4873     IDirect3DPixelShader9_Release(shader);
4874
4875     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4876     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4877     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4878     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4879 }
4880
4881 static void texkill_test(IDirect3DDevice9 *device)
4882 {
4883     IDirect3DPixelShader9 *shader;
4884     HRESULT hr;
4885     DWORD color;
4886
4887     const float vertex[] = {
4888     /*                          bottom  top    right    left */
4889         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4890          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4891         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4892          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4893     };
4894
4895     DWORD shader_code_11[] = {
4896     0xffff0101,                                                             /* ps_1_1                     */
4897     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4898     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4899     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4900     0x0000ffff                                                              /* end                        */
4901     };
4902     DWORD shader_code_20[] = {
4903     0xffff0200,                                                             /* ps_2_0                     */
4904     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4905     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4906     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4907     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4908     0x0000ffff                                                              /* end                        */
4909     };
4910
4911     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4912     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4913     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4914     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4915
4916     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4917     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4918     hr = IDirect3DDevice9_BeginScene(device);
4919     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4920     if(SUCCEEDED(hr))
4921     {
4922         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4923         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4924         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4925         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4926         hr = IDirect3DDevice9_EndScene(device);
4927         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4928     }
4929     color = getPixelColor(device, 63, 46);
4930     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4931     color = getPixelColor(device, 66, 46);
4932     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4933     color = getPixelColor(device, 63, 49);
4934     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4935     color = getPixelColor(device, 66, 49);
4936     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4937
4938     color = getPixelColor(device, 578, 46);
4939     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4940     color = getPixelColor(device, 575, 46);
4941     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4942     color = getPixelColor(device, 578, 49);
4943     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4944     color = getPixelColor(device, 575, 49);
4945     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4946
4947     color = getPixelColor(device, 63, 430);
4948     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4949     color = getPixelColor(device, 63, 433);
4950     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4951     color = getPixelColor(device, 66, 433);
4952     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4953     color = getPixelColor(device, 66, 430);
4954     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4955
4956     color = getPixelColor(device, 578, 430);
4957     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4958     color = getPixelColor(device, 578, 433);
4959     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4960     color = getPixelColor(device, 575, 433);
4961     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4962     color = getPixelColor(device, 575, 430);
4963     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4964
4965     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4966     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4967
4968     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4969     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4970     IDirect3DPixelShader9_Release(shader);
4971
4972     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4973     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4974     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4975     if(FAILED(hr)) {
4976         skip("Failed to create 2.0 test shader, most likely not supported\n");
4977         return;
4978     }
4979
4980     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4981     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4982     hr = IDirect3DDevice9_BeginScene(device);
4983     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4984     if(SUCCEEDED(hr))
4985     {
4986         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4987         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4988         hr = IDirect3DDevice9_EndScene(device);
4989         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4990     }
4991
4992     color = getPixelColor(device, 63, 46);
4993     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4994     color = getPixelColor(device, 66, 46);
4995     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4996     color = getPixelColor(device, 63, 49);
4997     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4998     color = getPixelColor(device, 66, 49);
4999     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
5000
5001     color = getPixelColor(device, 578, 46);
5002     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5003     color = getPixelColor(device, 575, 46);
5004     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5005     color = getPixelColor(device, 578, 49);
5006     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5007     color = getPixelColor(device, 575, 49);
5008     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5009
5010     color = getPixelColor(device, 63, 430);
5011     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5012     color = getPixelColor(device, 63, 433);
5013     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5014     color = getPixelColor(device, 66, 433);
5015     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5016     color = getPixelColor(device, 66, 430);
5017     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5018
5019     color = getPixelColor(device, 578, 430);
5020     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5021     color = getPixelColor(device, 578, 433);
5022     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5023     color = getPixelColor(device, 575, 433);
5024     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5025     color = getPixelColor(device, 575, 430);
5026     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5027
5028     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5029     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5030
5031     /* Cleanup */
5032     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5033     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
5034     IDirect3DPixelShader9_Release(shader);
5035 }
5036
5037 static void x8l8v8u8_test(IDirect3DDevice9 *device)
5038 {
5039     IDirect3D9 *d3d9;
5040     HRESULT hr;
5041     IDirect3DTexture9 *texture;
5042     IDirect3DPixelShader9 *shader;
5043     IDirect3DPixelShader9 *shader2;
5044     D3DLOCKED_RECT lr;
5045     DWORD color;
5046     DWORD shader_code[] = {
5047         0xffff0101,                             /* ps_1_1       */
5048         0x00000042, 0xb00f0000,                 /* tex t0       */
5049         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
5050         0x0000ffff                              /* end          */
5051     };
5052     DWORD shader_code2[] = {
5053         0xffff0101,                             /* ps_1_1       */
5054         0x00000042, 0xb00f0000,                 /* tex t0       */
5055         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
5056         0x0000ffff                              /* end          */
5057     };
5058
5059     float quad[] = {
5060        -1.0,   -1.0,   0.1,     0.5,    0.5,
5061         1.0,   -1.0,   0.1,     0.5,    0.5,
5062        -1.0,    1.0,   0.1,     0.5,    0.5,
5063         1.0,    1.0,   0.1,     0.5,    0.5,
5064     };
5065
5066     memset(&lr, 0, sizeof(lr));
5067     IDirect3DDevice9_GetDirect3D(device, &d3d9);
5068     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5069                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
5070     IDirect3D9_Release(d3d9);
5071     if(FAILED(hr)) {
5072         skip("No D3DFMT_X8L8V8U8 support\n");
5073         return;
5074     };
5075
5076     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5077     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5078
5079     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
5080     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
5081     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5082     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
5083     *((DWORD *) lr.pBits) = 0x11ca3141;
5084     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5085     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
5086
5087     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5088     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5089     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
5090     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5091
5092     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5093     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5094     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5095     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5096     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5097     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5098
5099     hr = IDirect3DDevice9_BeginScene(device);
5100     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5101     if(SUCCEEDED(hr))
5102     {
5103         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5104         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5105
5106         hr = IDirect3DDevice9_EndScene(device);
5107         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5108     }
5109     color = getPixelColor(device, 578, 430);
5110     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
5111        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
5112     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5113     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5114
5115     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
5116     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5117     hr = IDirect3DDevice9_BeginScene(device);
5118     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5119     if(SUCCEEDED(hr))
5120     {
5121         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5122         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5123
5124         hr = IDirect3DDevice9_EndScene(device);
5125         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5126     }
5127     color = getPixelColor(device, 578, 430);
5128     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
5129     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5130     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5131
5132     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5133     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5134     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5135     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5136     IDirect3DPixelShader9_Release(shader);
5137     IDirect3DPixelShader9_Release(shader2);
5138     IDirect3DTexture9_Release(texture);
5139 }
5140
5141 static void autogen_mipmap_test(IDirect3DDevice9 *device)
5142 {
5143     HRESULT hr;
5144     IDirect3D9 *d3d;
5145     IDirect3DTexture9 *texture = NULL;
5146     IDirect3DSurface9 *surface;
5147     DWORD color;
5148     const RECT r1 = {256, 256, 512, 512};
5149     const RECT r2 = {512, 256, 768, 512};
5150     const RECT r3 = {256, 512, 512, 768};
5151     const RECT r4 = {512, 512, 768, 768};
5152     unsigned int x, y;
5153     D3DLOCKED_RECT lr;
5154     memset(&lr, 0, sizeof(lr));
5155
5156     IDirect3DDevice9_GetDirect3D(device, &d3d);
5157     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5158        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
5159         skip("No autogenmipmap support\n");
5160         IDirect3D9_Release(d3d);
5161         return;
5162     }
5163     IDirect3D9_Release(d3d);
5164
5165     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5166     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5167
5168     /* Make the mipmap big, so that a smaller mipmap is used
5169      */
5170     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5171                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5172     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5173
5174     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5175     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5176     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5177     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5178     for(y = 0; y < 1024; y++) {
5179         for(x = 0; x < 1024; x++) {
5180             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5181             POINT pt;
5182
5183             pt.x = x;
5184             pt.y = y;
5185             if(PtInRect(&r1, pt)) {
5186                 *dst = 0xffff0000;
5187             } else if(PtInRect(&r2, pt)) {
5188                 *dst = 0xff00ff00;
5189             } else if(PtInRect(&r3, pt)) {
5190                 *dst = 0xff0000ff;
5191             } else if(PtInRect(&r4, pt)) {
5192                 *dst = 0xff000000;
5193             } else {
5194                 *dst = 0xffffffff;
5195             }
5196         }
5197     }
5198     hr = IDirect3DSurface9_UnlockRect(surface);
5199     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5200     IDirect3DSurface9_Release(surface);
5201
5202     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5203     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5204     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5205     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5206
5207     hr = IDirect3DDevice9_BeginScene(device);
5208     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5209     if(SUCCEEDED(hr)) {
5210         const float quad[] =  {
5211            -0.5,   -0.5,    0.1,    0.0,    0.0,
5212            -0.5,    0.5,    0.1,    0.0,    1.0,
5213             0.5,   -0.5,    0.1,    1.0,    0.0,
5214             0.5,    0.5,    0.1,    1.0,    1.0
5215         };
5216
5217         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5218         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5219         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5220         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5221         hr = IDirect3DDevice9_EndScene(device);
5222         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5223     }
5224     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5225     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5226     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
5227     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5228     IDirect3DTexture9_Release(texture);
5229
5230     color = getPixelColor(device, 200, 200);
5231     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5232     color = getPixelColor(device, 280, 200);
5233     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5234     color = getPixelColor(device, 360, 200);
5235     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5236     color = getPixelColor(device, 440, 200);
5237     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5238     color = getPixelColor(device, 200, 270);
5239     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5240     color = getPixelColor(device, 280, 270);
5241     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5242     color = getPixelColor(device, 360, 270);
5243     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5244     color = getPixelColor(device, 440, 270);
5245     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5246     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5247     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5248 }
5249
5250 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
5251 {
5252     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5253     IDirect3DVertexDeclaration9 *decl;
5254     HRESULT hr;
5255     DWORD color;
5256     DWORD shader_code_11[] =  {
5257         0xfffe0101,                                         /* vs_1_1           */
5258         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5259         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5260         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5261         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5262         0x0000ffff                                          /* end              */
5263     };
5264     DWORD shader_code_11_2[] =  {
5265         0xfffe0101,                                         /* vs_1_1           */
5266         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
5267         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
5268         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5269         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5270         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5271         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5272         0x0000ffff                                          /* end              */
5273     };
5274     DWORD shader_code_20[] =  {
5275         0xfffe0200,                                         /* vs_2_0           */
5276         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5277         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5278         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5279         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5280         0x0000ffff                                          /* end              */
5281     };
5282     DWORD shader_code_20_2[] =  {
5283         0xfffe0200,                                         /* vs_2_0           */
5284         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
5285         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
5286         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5287         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5288         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5289         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5290         0x0000ffff                                          /* end              */
5291     };
5292     static const D3DVERTEXELEMENT9 decl_elements[] = {
5293         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5294         D3DDECL_END()
5295     };
5296     float quad1[] = {
5297         -1.0,   -1.0,   0.1,
5298          0.0,   -1.0,   0.1,
5299         -1.0,    0.0,   0.1,
5300          0.0,    0.0,   0.1
5301     };
5302     float quad2[] = {
5303          0.0,   -1.0,   0.1,
5304          1.0,   -1.0,   0.1,
5305          0.0,    0.0,   0.1,
5306          1.0,    0.0,   0.1
5307     };
5308     float quad3[] = {
5309          0.0,    0.0,   0.1,
5310          1.0,    0.0,   0.1,
5311          0.0,    1.0,   0.1,
5312          1.0,    1.0,   0.1
5313     };
5314     float quad4[] = {
5315         -1.0,    0.0,   0.1,
5316          0.0,    0.0,   0.1,
5317         -1.0,    1.0,   0.1,
5318          0.0,    1.0,   0.1
5319     };
5320     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
5321     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
5322
5323     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5324     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5325
5326     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
5327     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5328     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
5329     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5330     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
5331     if(FAILED(hr)) shader_20 = NULL;
5332     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
5333     if(FAILED(hr)) shader_20_2 = NULL;
5334     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5335     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5336
5337     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
5338     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5339     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
5340     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5341     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5342     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5343
5344     hr = IDirect3DDevice9_BeginScene(device);
5345     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5346     if(SUCCEEDED(hr))
5347     {
5348         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
5349         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5350         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5351         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5352
5353         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
5354         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5355         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5356         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5357
5358         if(shader_20) {
5359             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
5360             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5361             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5362             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5363         }
5364
5365         if(shader_20_2) {
5366             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
5367             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5368             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5369             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5370         }
5371
5372         hr = IDirect3DDevice9_EndScene(device);
5373         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5374     }
5375
5376     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5377     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5378     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5379     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5380
5381     color = getPixelColor(device, 160, 360);
5382     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5383        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
5384     color = getPixelColor(device, 480, 360);
5385     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5386        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
5387     if(shader_20) {
5388         color = getPixelColor(device, 480, 120);
5389         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5390            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
5391     }
5392     if(shader_20_2) {
5393         color = getPixelColor(device, 160, 120);
5394         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5395            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5396     }
5397     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5398     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5399
5400     IDirect3DVertexDeclaration9_Release(decl);
5401     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
5402     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
5403     IDirect3DVertexShader9_Release(shader_11_2);
5404     IDirect3DVertexShader9_Release(shader_11);
5405 }
5406
5407 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
5408 {
5409     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
5410     HRESULT hr;
5411     DWORD color;
5412     DWORD shader_code_11[] =  {
5413         0xffff0101,                                         /* ps_1_1           */
5414         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5415         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5416         0x0000ffff                                          /* end              */
5417     };
5418     DWORD shader_code_12[] =  {
5419         0xffff0102,                                         /* ps_1_2           */
5420         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5421         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5422         0x0000ffff                                          /* end              */
5423     };
5424     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
5425      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
5426      * During development of this test, 1.3 shaders were verified too
5427      */
5428     DWORD shader_code_14[] =  {
5429         0xffff0104,                                         /* ps_1_4           */
5430         /* Try to make one constant local. It gets clamped too, although the binary contains
5431          * the bigger numbers
5432          */
5433         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
5434         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5435         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5436         0x0000ffff                                          /* end              */
5437     };
5438     DWORD shader_code_20[] =  {
5439         0xffff0200,                                         /* ps_2_0           */
5440         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5441         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5442         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
5443         0x0000ffff                                          /* end              */
5444     };
5445     float quad1[] = {
5446         -1.0,   -1.0,   0.1,
5447          0.0,   -1.0,   0.1,
5448         -1.0,    0.0,   0.1,
5449          0.0,    0.0,   0.1
5450     };
5451     float quad2[] = {
5452          0.0,   -1.0,   0.1,
5453          1.0,   -1.0,   0.1,
5454          0.0,    0.0,   0.1,
5455          1.0,    0.0,   0.1
5456     };
5457     float quad3[] = {
5458          0.0,    0.0,   0.1,
5459          1.0,    0.0,   0.1,
5460          0.0,    1.0,   0.1,
5461          1.0,    1.0,   0.1
5462     };
5463     float quad4[] = {
5464         -1.0,    0.0,   0.1,
5465          0.0,    0.0,   0.1,
5466         -1.0,    1.0,   0.1,
5467          0.0,    1.0,   0.1
5468     };
5469     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
5470     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
5471
5472     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5473     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5474
5475     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5476     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5477     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5478     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5479     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5480     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5481     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
5482     if(FAILED(hr)) shader_20 = NULL;
5483
5484     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5485     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5486     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5487     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5488     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5489     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5490
5491     hr = IDirect3DDevice9_BeginScene(device);
5492     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5493     if(SUCCEEDED(hr))
5494     {
5495         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5496         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5497         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5498         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5499
5500         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5501         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5502         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5503         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5504
5505         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5506         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5507         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5508         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5509
5510         if(shader_20) {
5511             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
5512             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5513             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5514             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5515         }
5516
5517         hr = IDirect3DDevice9_EndScene(device);
5518         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5519     }
5520     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5521     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5522
5523     color = getPixelColor(device, 160, 360);
5524     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5525        "quad 1 has color %08x, expected 0x00808000\n", color);
5526     color = getPixelColor(device, 480, 360);
5527     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5528        "quad 2 has color %08x, expected 0x00808000\n", color);
5529     color = getPixelColor(device, 480, 120);
5530     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5531        "quad 3 has color %08x, expected 0x00808000\n", color);
5532     if(shader_20) {
5533         color = getPixelColor(device, 160, 120);
5534         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5535            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5536     }
5537     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5538     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5539
5540     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5541     IDirect3DPixelShader9_Release(shader_14);
5542     IDirect3DPixelShader9_Release(shader_12);
5543     IDirect3DPixelShader9_Release(shader_11);
5544 }
5545
5546 static void dp2add_ps_test(IDirect3DDevice9 *device)
5547 {
5548     IDirect3DPixelShader9 *shader_dp2add = NULL;
5549     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5550     HRESULT hr;
5551     DWORD color;
5552
5553     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
5554      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5555      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
5556      * r0 first.
5557      * The result here for the r,g,b components should be roughly 0.5:
5558      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5559     static const DWORD shader_code_dp2add[] =  {
5560         0xffff0200,                                                             /* ps_2_0                       */
5561         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
5562
5563         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5564         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
5565
5566         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
5567         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5568         0x0000ffff                                                              /* end                          */
5569     };
5570
5571     /* Test the _sat modifier, too.  Result here should be:
5572      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5573      *      _SAT: ==> 1.0
5574      *   ADD: (1.0 + -0.5) = 0.5
5575      */
5576     static const DWORD shader_code_dp2add_sat[] =  {
5577         0xffff0200,                                                             /* ps_2_0                           */
5578         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
5579
5580         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
5581         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
5582         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5583
5584         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5585         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5586         0x0000ffff                                                              /* end                              */
5587     };
5588
5589     const float quad[] = {
5590         -1.0,   -1.0,   0.1,
5591          1.0,   -1.0,   0.1,
5592         -1.0,    1.0,   0.1,
5593          1.0,    1.0,   0.1
5594     };
5595
5596
5597     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5598     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5599
5600     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5601     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5602
5603     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5604     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5605
5606     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5607     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5608
5609     if (shader_dp2add) {
5610
5611         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5612         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5613
5614         hr = IDirect3DDevice9_BeginScene(device);
5615         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5616         if(SUCCEEDED(hr))
5617         {
5618             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5619             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5620
5621             hr = IDirect3DDevice9_EndScene(device);
5622             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5623         }
5624
5625         color = getPixelColor(device, 360, 240);
5626         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5627                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5628
5629         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5630         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5631
5632         IDirect3DPixelShader9_Release(shader_dp2add);
5633     } else {
5634         skip("dp2add shader creation failed\n");
5635     }
5636
5637     if (shader_dp2add_sat) {
5638
5639         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5640         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5641
5642         hr = IDirect3DDevice9_BeginScene(device);
5643         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5644         if(SUCCEEDED(hr))
5645         {
5646             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5647             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5648
5649             hr = IDirect3DDevice9_EndScene(device);
5650             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5651         }
5652
5653         color = getPixelColor(device, 360, 240);
5654         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5655                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5656
5657         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5658         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5659
5660         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5661     } else {
5662         skip("dp2add shader creation failed\n");
5663     }
5664
5665     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5666     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5667 }
5668
5669 static void cnd_test(IDirect3DDevice9 *device)
5670 {
5671     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5672     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5673     HRESULT hr;
5674     DWORD color;
5675     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5676      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5677      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5678      */
5679     DWORD shader_code_11[] =  {
5680         0xffff0101,                                                                 /* ps_1_1               */
5681         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5682         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5683         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5684         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5685         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5686         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5687         0x0000ffff                                                                  /* end                  */
5688     };
5689     DWORD shader_code_12[] =  {
5690         0xffff0102,                                                                 /* ps_1_2               */
5691         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5692         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5693         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5694         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5695         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5696         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5697         0x0000ffff                                                                  /* end                  */
5698     };
5699     DWORD shader_code_13[] =  {
5700         0xffff0103,                                                                 /* ps_1_3               */
5701         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5702         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5703         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5704         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5705         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5706         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5707         0x0000ffff                                                                  /* end                  */
5708     };
5709     DWORD shader_code_14[] =  {
5710         0xffff0104,                                                                 /* ps_1_3               */
5711         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5712         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5713         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5714         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5715         0x0000ffff                                                                  /* end                  */
5716     };
5717
5718     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5719      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5720      * set by the compiler, it was added manually after compilation. Note that the COISSUE
5721      * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5722      * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5723      * well enough.
5724      *
5725      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5726      * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5727      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5728      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5729      */
5730     DWORD shader_code_11_coissue[] =  {
5731         0xffff0101,                                                             /* ps_1_1                   */
5732         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5733         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5734         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5735         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5736         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5737         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5738         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5739         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5740         /* 0x40000000 = D3DSI_COISSUE */
5741         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5742         0x0000ffff                                                              /* end                      */
5743     };
5744     DWORD shader_code_12_coissue[] =  {
5745         0xffff0102,                                                             /* ps_1_2                   */
5746         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5747         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5748         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5749         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5750         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5751         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5752         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5753         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5754         /* 0x40000000 = D3DSI_COISSUE */
5755         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5756         0x0000ffff                                                              /* end                      */
5757     };
5758     DWORD shader_code_13_coissue[] =  {
5759         0xffff0103,                                                             /* ps_1_3                   */
5760         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5761         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5762         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5763         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5764         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5765         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5766         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5767         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5768         /* 0x40000000 = D3DSI_COISSUE */
5769         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5770         0x0000ffff                                                              /* end                      */
5771     };
5772     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5773      * compare against 0.5
5774      */
5775     DWORD shader_code_14_coissue[] =  {
5776         0xffff0104,                                                             /* ps_1_4                   */
5777         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5778         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5779         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5780         /* 0x40000000 = D3DSI_COISSUE */
5781         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5782         0x0000ffff                                                              /* end                      */
5783     };
5784     float quad1[] = {
5785         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5786          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5787         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5788          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5789     };
5790     float quad2[] = {
5791          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5792          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5793          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5794          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5795     };
5796     float quad3[] = {
5797          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5798          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5799          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5800          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5801     };
5802     float quad4[] = {
5803         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5804          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5805         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5806          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5807     };
5808     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5809     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5810     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5811     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5812
5813     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5814     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5815
5816     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5817     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5818     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5819     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5820     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5821     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5822     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5823     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5824     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5825     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5826     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5827     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5828     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5829     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5830     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5831     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5832
5833     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5834     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5835     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5836     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5837     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5838     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5839
5840     hr = IDirect3DDevice9_BeginScene(device);
5841     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5842     if(SUCCEEDED(hr))
5843     {
5844         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5845         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5846         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5847         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5848
5849         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5850         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5851         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5852         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5853
5854         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5855         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5856         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5857         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5858
5859         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5860         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5861         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5862         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5863
5864         hr = IDirect3DDevice9_EndScene(device);
5865         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5866     }
5867
5868     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5869     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5870
5871     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5872     color = getPixelColor(device, 158, 118);
5873     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5874     color = getPixelColor(device, 162, 118);
5875     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5876     color = getPixelColor(device, 158, 122);
5877     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5878     color = getPixelColor(device, 162, 122);
5879     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5880
5881     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5882     color = getPixelColor(device, 158, 358);
5883     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5884     color = getPixelColor(device, 162, 358);
5885     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5886         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5887     color = getPixelColor(device, 158, 362);
5888     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5889     color = getPixelColor(device, 162, 362);
5890     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5891         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5892
5893     /* 1.2 shader */
5894     color = getPixelColor(device, 478, 358);
5895     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5896     color = getPixelColor(device, 482, 358);
5897     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5898         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5899     color = getPixelColor(device, 478, 362);
5900     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5901     color = getPixelColor(device, 482, 362);
5902     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5903         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5904
5905     /* 1.3 shader */
5906     color = getPixelColor(device, 478, 118);
5907     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5908     color = getPixelColor(device, 482, 118);
5909     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5910         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5911     color = getPixelColor(device, 478, 122);
5912     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5913     color = getPixelColor(device, 482, 122);
5914     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5915         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5916
5917     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5918     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5919
5920     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5921     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5922     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5923     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5924     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5925     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5926
5927     hr = IDirect3DDevice9_BeginScene(device);
5928     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5929     if(SUCCEEDED(hr))
5930     {
5931         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5932         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5933         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5934         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5935
5936         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5937         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5938         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5939         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5940
5941         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5942         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5943         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5944         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5945
5946         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5947         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5948         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5949         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5950
5951         hr = IDirect3DDevice9_EndScene(device);
5952         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5953     }
5954
5955     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5956     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5957
5958     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5959      * that we swapped the values in c1 and c2 to make the other tests return some color
5960      */
5961     color = getPixelColor(device, 158, 118);
5962     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5963     color = getPixelColor(device, 162, 118);
5964     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5965     color = getPixelColor(device, 158, 122);
5966     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5967     color = getPixelColor(device, 162, 122);
5968     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5969
5970     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5971      * (The Win7 nvidia driver always selects c2)
5972      */
5973     color = getPixelColor(device, 158, 358);
5974     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5975         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5976     color = getPixelColor(device, 162, 358);
5977     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5978         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5979     color = getPixelColor(device, 158, 362);
5980     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5981         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5982     color = getPixelColor(device, 162, 362);
5983     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5984         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5985
5986     /* 1.2 shader */
5987     color = getPixelColor(device, 478, 358);
5988     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5989         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5990     color = getPixelColor(device, 482, 358);
5991     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5992         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5993     color = getPixelColor(device, 478, 362);
5994     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5995         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5996     color = getPixelColor(device, 482, 362);
5997     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5998         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5999
6000     /* 1.3 shader */
6001     color = getPixelColor(device, 478, 118);
6002     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
6003         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
6004     color = getPixelColor(device, 482, 118);
6005     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
6006         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
6007     color = getPixelColor(device, 478, 122);
6008     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
6009         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
6010     color = getPixelColor(device, 482, 122);
6011     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
6012         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
6013
6014     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6015     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6016
6017     IDirect3DPixelShader9_Release(shader_14_coissue);
6018     IDirect3DPixelShader9_Release(shader_13_coissue);
6019     IDirect3DPixelShader9_Release(shader_12_coissue);
6020     IDirect3DPixelShader9_Release(shader_11_coissue);
6021     IDirect3DPixelShader9_Release(shader_14);
6022     IDirect3DPixelShader9_Release(shader_13);
6023     IDirect3DPixelShader9_Release(shader_12);
6024     IDirect3DPixelShader9_Release(shader_11);
6025 }
6026
6027 static void nested_loop_test(IDirect3DDevice9 *device) {
6028     const DWORD shader_code[] = {
6029         0xffff0300,                                                             /* ps_3_0               */
6030         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
6031         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
6032         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
6033         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
6034         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
6035         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
6036         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
6037         0x0000001d,                                                             /* endloop              */
6038         0x0000001d,                                                             /* endloop              */
6039         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
6040         0x0000ffff                                                              /* end                  */
6041     };
6042     const DWORD vshader_code[] = {
6043         0xfffe0300,                                                             /* vs_3_0               */
6044         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
6045         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
6046         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
6047         0x0000ffff                                                              /* end                  */
6048     };
6049     IDirect3DPixelShader9 *shader;
6050     IDirect3DVertexShader9 *vshader;
6051     HRESULT hr;
6052     DWORD color;
6053     const float quad[] = {
6054         -1.0,   -1.0,   0.1,
6055          1.0,   -1.0,   0.1,
6056         -1.0,    1.0,   0.1,
6057          1.0,    1.0,   0.1
6058     };
6059
6060     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
6061     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
6062     hr = IDirect3DDevice9_SetPixelShader(device, shader);
6063     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
6064     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6065     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
6066     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6067     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
6068     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6069     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6070     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
6071     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6072
6073     hr = IDirect3DDevice9_BeginScene(device);
6074     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6075     if(SUCCEEDED(hr))
6076     {
6077         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6078         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6079         hr = IDirect3DDevice9_EndScene(device);
6080         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6081     }
6082
6083     color = getPixelColor(device, 360, 240);
6084     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
6085        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
6086
6087     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6088     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6089
6090     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6091     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
6092     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6093     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
6094     IDirect3DPixelShader9_Release(shader);
6095     IDirect3DVertexShader9_Release(vshader);
6096 }
6097
6098 struct varying_test_struct
6099 {
6100     const DWORD             *shader_code;
6101     IDirect3DPixelShader9   *shader;
6102     DWORD                   color, color_rhw;
6103     const char              *name;
6104     BOOL                    todo, todo_rhw;
6105 };
6106
6107 struct hugeVertex
6108 {
6109     float pos_x,        pos_y,      pos_z,      rhw;
6110     float weight_1,     weight_2,   weight_3,   weight_4;
6111     float index_1,      index_2,    index_3,    index_4;
6112     float normal_1,     normal_2,   normal_3,   normal_4;
6113     float fog_1,        fog_2,      fog_3,      fog_4;
6114     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
6115     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
6116     float binormal_1,   binormal_2, binormal_3, binormal_4;
6117     float depth_1,      depth_2,    depth_3,    depth_4;
6118     DWORD diffuse, specular;
6119 };
6120
6121 static void pretransformed_varying_test(IDirect3DDevice9 *device) {
6122     /* dcl_position: fails to compile */
6123     const DWORD blendweight_code[] = {
6124         0xffff0300,                             /* ps_3_0                   */
6125         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
6126         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6127         0x0000ffff                              /* end                      */
6128     };
6129     const DWORD blendindices_code[] = {
6130         0xffff0300,                             /* ps_3_0                   */
6131         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
6132         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6133         0x0000ffff                              /* end                      */
6134     };
6135     const DWORD normal_code[] = {
6136         0xffff0300,                             /* ps_3_0                   */
6137         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
6138         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6139         0x0000ffff                              /* end                      */
6140     };
6141     /* psize: fails? */
6142     const DWORD texcoord0_code[] = {
6143         0xffff0300,                             /* ps_3_0                   */
6144         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
6145         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6146         0x0000ffff                              /* end                      */
6147     };
6148     const DWORD tangent_code[] = {
6149         0xffff0300,                             /* ps_3_0                   */
6150         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
6151         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6152         0x0000ffff                              /* end                      */
6153     };
6154     const DWORD binormal_code[] = {
6155         0xffff0300,                             /* ps_3_0                   */
6156         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
6157         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6158         0x0000ffff                              /* end                      */
6159     };
6160     /* tessfactor: fails */
6161     /* positiont: fails */
6162     const DWORD color_code[] = {
6163         0xffff0300,                             /* ps_3_0                   */
6164         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
6165         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6166         0x0000ffff                              /* end                      */
6167     };
6168     const DWORD fog_code[] = {
6169         0xffff0300,                             /* ps_3_0                   */
6170         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
6171         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6172         0x0000ffff                              /* end                      */
6173     };
6174     const DWORD depth_code[] = {
6175         0xffff0300,                             /* ps_3_0                   */
6176         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
6177         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6178         0x0000ffff                              /* end                      */
6179     };
6180     const DWORD specular_code[] = {
6181         0xffff0300,                             /* ps_3_0                   */
6182         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
6183         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6184         0x0000ffff                              /* end                      */
6185     };
6186     /* sample: fails */
6187
6188     struct varying_test_struct tests[] = {
6189        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
6190        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
6191        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
6192        /* Why does dx not forward the texcoord? */
6193        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
6194        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
6195        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
6196        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
6197        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
6198        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
6199        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
6200     };
6201     /* Declare a monster vertex type :-) */
6202     static const D3DVERTEXELEMENT9 decl_elements[] = {
6203         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6204         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
6205         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
6206         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
6207         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
6208         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6209         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
6210         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
6211         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
6212         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6213         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
6214         D3DDECL_END()
6215     };
6216     struct hugeVertex data[4] = {
6217         {
6218             -1.0,   -1.0,   0.1,    1.0,
6219              0.1,    0.1,   0.1,    0.1,
6220              0.2,    0.2,   0.2,    0.2,
6221              0.3,    0.3,   0.3,    0.3,
6222              0.4,    0.4,   0.4,    0.4,
6223              0.50,   0.55,  0.55,   0.55,
6224              0.6,    0.6,   0.6,    0.7,
6225              0.7,    0.7,   0.7,    0.6,
6226              0.8,    0.8,   0.8,    0.8,
6227              0xe6e6e6e6, /* 0.9 * 256 */
6228              0x224488ff  /* Nothing special */
6229         },
6230         {
6231              1.0,   -1.0,   0.1,    1.0,
6232              0.1,    0.1,   0.1,    0.1,
6233              0.2,    0.2,   0.2,    0.2,
6234              0.3,    0.3,   0.3,    0.3,
6235              0.4,    0.4,   0.4,    0.4,
6236              0.50,   0.55,  0.55,   0.55,
6237              0.6,    0.6,   0.6,    0.7,
6238              0.7,    0.7,   0.7,    0.6,
6239              0.8,    0.8,   0.8,    0.8,
6240              0xe6e6e6e6, /* 0.9 * 256 */
6241              0x224488ff /* Nothing special */
6242         },
6243         {
6244             -1.0,    1.0,   0.1,    1.0,
6245              0.1,    0.1,   0.1,    0.1,
6246              0.2,    0.2,   0.2,    0.2,
6247              0.3,    0.3,   0.3,    0.3,
6248              0.4,    0.4,   0.4,    0.4,
6249              0.50,   0.55,  0.55,   0.55,
6250              0.6,    0.6,   0.6,    0.7,
6251              0.7,    0.7,   0.7,    0.6,
6252              0.8,    0.8,   0.8,    0.8,
6253              0xe6e6e6e6, /* 0.9 * 256 */
6254              0x224488ff /* Nothing special */
6255         },
6256         {
6257              1.0,    1.0,   0.1,    1.0,
6258              0.1,    0.1,   0.1,    0.1,
6259              0.2,    0.2,   0.2,    0.2,
6260              0.3,    0.3,   0.3,    0.3,
6261              0.4,    0.4,   0.4,    0.4,
6262              0.50,   0.55,  0.55,   0.55,
6263              0.6,    0.6,   0.6,    0.7,
6264              0.7,    0.7,   0.7,    0.6,
6265              0.8,    0.8,   0.8,    0.8,
6266              0xe6e6e6e6, /* 0.9 * 256 */
6267              0x224488ff /* Nothing special */
6268         },
6269     };
6270     struct hugeVertex data2[4];
6271     IDirect3DVertexDeclaration9 *decl;
6272     HRESULT hr;
6273     unsigned int i;
6274     DWORD color, r, g, b, r_e, g_e, b_e;
6275
6276     memcpy(data2, data, sizeof(data2));
6277     data2[0].pos_x = 0;     data2[0].pos_y = 0;
6278     data2[1].pos_x = 640;   data2[1].pos_y = 0;
6279     data2[2].pos_x = 0;     data2[2].pos_y = 480;
6280     data2[3].pos_x = 640;   data2[3].pos_y = 480;
6281
6282     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6283     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6284     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6285     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6286
6287     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6288     {
6289         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
6290         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
6291            tests[i].name, hr);
6292     }
6293
6294     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6295     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6296     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6297     {
6298         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6299         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6300
6301         hr = IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
6302         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6303
6304         hr = IDirect3DDevice9_BeginScene(device);
6305         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6306         if(SUCCEEDED(hr))
6307         {
6308             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
6309             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6310             hr = IDirect3DDevice9_EndScene(device);
6311             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6312         }
6313
6314         color = getPixelColor(device, 360, 240);
6315         r = color & 0x00ff0000 >> 16;
6316         g = color & 0x0000ff00 >>  8;
6317         b = color & 0x000000ff;
6318         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
6319         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
6320         b_e = tests[i].color_rhw & 0x000000ff;
6321
6322         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6323         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6324
6325         if(tests[i].todo_rhw) {
6326             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
6327              * pipeline
6328              */
6329             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6330                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
6331                          tests[i].name, color, tests[i].color_rhw);
6332         } else {
6333             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6334                "Test %s returned color 0x%08x, expected 0x%08x\n",
6335                tests[i].name, color, tests[i].color_rhw);
6336         }
6337     }
6338
6339     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6340     {
6341         IDirect3DPixelShader9_Release(tests[i].shader);
6342     }
6343
6344     IDirect3DVertexDeclaration9_Release(decl);
6345 }
6346
6347 static void test_compare_instructions(IDirect3DDevice9 *device)
6348 {
6349     DWORD shader_sge_vec_code[] = {
6350         0xfffe0101,                                         /* vs_1_1                   */
6351         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6352         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6353         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6354         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
6355         0x0000ffff                                          /* end                      */
6356     };
6357     DWORD shader_slt_vec_code[] = {
6358         0xfffe0101,                                         /* vs_1_1                   */
6359         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6360         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6361         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6362         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
6363         0x0000ffff                                          /* end                      */
6364     };
6365     DWORD shader_sge_scalar_code[] = {
6366         0xfffe0101,                                         /* vs_1_1                   */
6367         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6368         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6369         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6370         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
6371         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
6372         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
6373         0x0000ffff                                          /* end                      */
6374     };
6375     DWORD shader_slt_scalar_code[] = {
6376         0xfffe0101,                                         /* vs_1_1                   */
6377         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6378         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6379         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6380         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
6381         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
6382         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
6383         0x0000ffff                                          /* end                      */
6384     };
6385     IDirect3DVertexShader9 *shader_sge_vec;
6386     IDirect3DVertexShader9 *shader_slt_vec;
6387     IDirect3DVertexShader9 *shader_sge_scalar;
6388     IDirect3DVertexShader9 *shader_slt_scalar;
6389     HRESULT hr, color;
6390     float quad1[] =  {
6391         -1.0,   -1.0,   0.1,
6392          0.0,   -1.0,   0.1,
6393         -1.0,    0.0,   0.1,
6394          0.0,    0.0,   0.1
6395     };
6396     float quad2[] =  {
6397          0.0,   -1.0,   0.1,
6398          1.0,   -1.0,   0.1,
6399          0.0,    0.0,   0.1,
6400          1.0,    0.0,   0.1
6401     };
6402     float quad3[] =  {
6403         -1.0,    0.0,   0.1,
6404          0.0,    0.0,   0.1,
6405         -1.0,    1.0,   0.1,
6406          0.0,    1.0,   0.1
6407     };
6408     float quad4[] =  {
6409          0.0,    0.0,   0.1,
6410          1.0,    0.0,   0.1,
6411          0.0,    1.0,   0.1,
6412          1.0,    1.0,   0.1
6413     };
6414     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6415     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6416
6417     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6418     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6419
6420     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6421     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6422     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6423     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6424     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6425     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6426     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6427     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6428     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6429     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6430     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6431     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6432     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6433     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6434
6435     hr = IDirect3DDevice9_BeginScene(device);
6436     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6437     if(SUCCEEDED(hr))
6438     {
6439         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6440         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6441         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6442         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6443
6444         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6445         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6446         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6447         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6448
6449         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6450         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6451         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6452         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6453
6454         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6455         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6456
6457         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6458         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6459         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6460         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6461
6462         hr = IDirect3DDevice9_EndScene(device);
6463         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6464     }
6465
6466     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6467     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6468
6469     color = getPixelColor(device, 160, 360);
6470     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6471     color = getPixelColor(device, 480, 360);
6472     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6473     color = getPixelColor(device, 160, 120);
6474     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6475     color = getPixelColor(device, 480, 160);
6476     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6477
6478     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6479     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6480
6481     IDirect3DVertexShader9_Release(shader_sge_vec);
6482     IDirect3DVertexShader9_Release(shader_slt_vec);
6483     IDirect3DVertexShader9_Release(shader_sge_scalar);
6484     IDirect3DVertexShader9_Release(shader_slt_scalar);
6485 }
6486
6487 static void test_vshader_input(IDirect3DDevice9 *device)
6488 {
6489     static const DWORD swapped_shader_code_3[] =
6490     {
6491         0xfffe0300,                                         /* vs_3_0               */
6492         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6493         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6494         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6495         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6496         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6497         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6498         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6499         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6500         0x0000ffff                                          /* end                  */
6501     };
6502     static const DWORD swapped_shader_code_1[] =
6503     {
6504         0xfffe0101,                                         /* vs_1_1               */
6505         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6506         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6507         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6508         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6509         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6510         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6511         0x0000ffff                                          /* end                  */
6512     };
6513     static const DWORD swapped_shader_code_2[] =
6514     {
6515         0xfffe0200,                                         /* vs_2_0               */
6516         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6517         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6518         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6519         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6520         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6521         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6522         0x0000ffff                                          /* end                  */
6523     };
6524     static const DWORD texcoord_color_shader_code_3[] =
6525     {
6526         0xfffe0300,                                         /* vs_3_0               */
6527         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6528         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6529         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6530         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6531         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6532         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6533         0x0000ffff                                          /* end                  */
6534     };
6535     static const DWORD texcoord_color_shader_code_2[] =
6536     {
6537         0xfffe0200,                                         /* vs_2_0               */
6538         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6539         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6540         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6541         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6542         0x0000ffff                                          /* end                  */
6543     };
6544     static const DWORD texcoord_color_shader_code_1[] =
6545     {
6546         0xfffe0101,                                         /* vs_1_1               */
6547         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6548         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6549         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6550         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6551         0x0000ffff                                          /* end                  */
6552     };
6553     static const DWORD color_color_shader_code_3[] =
6554     {
6555         0xfffe0300,                                         /* vs_3_0               */
6556         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6557         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6558         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6559         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6560         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6561         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6562         0x0000ffff                                          /* end                  */
6563     };
6564     static const DWORD color_color_shader_code_2[] =
6565     {
6566         0xfffe0200,                                         /* vs_2_0               */
6567         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6568         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6569         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6570         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6571         0x0000ffff                                          /* end                  */
6572     };
6573     static const DWORD color_color_shader_code_1[] =
6574     {
6575         0xfffe0101,                                         /* vs_1_1               */
6576         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6577         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6578         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6579         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6580         0x0000ffff                                          /* end                  */
6581     };
6582     static const DWORD ps3_code[] =
6583     {
6584         0xffff0300,                                         /* ps_3_0               */
6585         0x0200001f, 0x8000000a, 0x900f0000,                 /* dcl_color0 v0        */
6586         0x02000001, 0x800f0800, 0x90e40000,                 /* mov oC0, v0          */
6587         0x0000ffff                                          /* end                  */
6588     };
6589     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6590     IDirect3DPixelShader9 *ps;
6591     HRESULT hr;
6592     DWORD color;
6593     float quad1[] =  {
6594         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6595          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6596         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6597          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6598     };
6599     float quad2[] =  {
6600          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6601          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6602          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6603          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6604     };
6605     float quad3[] =  {
6606         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6607          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6608         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6609          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6610     };
6611     float quad4[] =  {
6612          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6613          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6614          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6615          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6616     };
6617     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6618         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6619         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6620         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6621         D3DDECL_END()
6622     };
6623     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6624         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6625         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6626         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6627         D3DDECL_END()
6628     };
6629     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6630         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6631         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6632         D3DDECL_END()
6633     };
6634     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6635         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6636         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6637         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6638         D3DDECL_END()
6639     };
6640     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6641         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6642         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6643         D3DDECL_END()
6644     };
6645     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6646         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6647         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6648         D3DDECL_END()
6649     };
6650     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6651         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6652         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6653         D3DDECL_END()
6654     };
6655     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6656         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6657         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6658         D3DDECL_END()
6659     };
6660     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6661     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6662     unsigned int i;
6663     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6664     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6665
6666     struct vertex quad1_color[] =  {
6667        {-1.0,   -1.0,   0.1,    0x00ff8040},
6668        { 0.0,   -1.0,   0.1,    0x00ff8040},
6669        {-1.0,    0.0,   0.1,    0x00ff8040},
6670        { 0.0,    0.0,   0.1,    0x00ff8040}
6671     };
6672     struct vertex quad2_color[] =  {
6673        { 0.0,   -1.0,   0.1,    0x00ff8040},
6674        { 1.0,   -1.0,   0.1,    0x00ff8040},
6675        { 0.0,    0.0,   0.1,    0x00ff8040},
6676        { 1.0,    0.0,   0.1,    0x00ff8040}
6677     };
6678     struct vertex quad3_color[] =  {
6679        {-1.0,    0.0,   0.1,    0x00ff8040},
6680        { 0.0,    0.0,   0.1,    0x00ff8040},
6681        {-1.0,    1.0,   0.1,    0x00ff8040},
6682        { 0.0,    1.0,   0.1,    0x00ff8040}
6683     };
6684     float quad4_color[] =  {
6685          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6686          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6687          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6688          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6689     };
6690
6691     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6692     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6693     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6694     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6695     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6696     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6697     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6698     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6699
6700     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6701     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6702     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6703     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6704     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6705     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6706     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6707     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6708
6709     hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
6710     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6711
6712     for(i = 1; i <= 3; i++) {
6713         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6714         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6715         if(i == 3) {
6716             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6717             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6718             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6719             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6720         } else if(i == 2){
6721             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6722             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6723         } else if(i == 1) {
6724             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6725             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6726         }
6727
6728         hr = IDirect3DDevice9_BeginScene(device);
6729         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6730         if(SUCCEEDED(hr))
6731         {
6732             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6733             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6734
6735             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6736             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6737             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6738             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6739
6740             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6741             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6742             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6743             if(i == 3 || i == 2) {
6744                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6745             } else if(i == 1) {
6746                 /* Succeeds or fails, depending on SW or HW vertex processing */
6747                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6748             }
6749
6750             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6751             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6752             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6753             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6754
6755             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6756             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6757             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6758             if(i == 3 || i == 2) {
6759                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6760             } else if(i == 1) {
6761                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6762             }
6763
6764             hr = IDirect3DDevice9_EndScene(device);
6765             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6766         }
6767
6768         if(i == 3 || i == 2) {
6769             color = getPixelColor(device, 160, 360);
6770             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6771                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6772
6773             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6774             color = getPixelColor(device, 480, 360);
6775             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6776                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6777             color = getPixelColor(device, 160, 120);
6778             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6779             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6780                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6781
6782             color = getPixelColor(device, 480, 160);
6783             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6784         } else if(i == 1) {
6785             color = getPixelColor(device, 160, 360);
6786             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6787                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6788             color = getPixelColor(device, 480, 360);
6789             /* Accept the clear color as well in this case, since SW VP returns an error */
6790             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6791             color = getPixelColor(device, 160, 120);
6792             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6793                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6794             color = getPixelColor(device, 480, 160);
6795             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6796         }
6797
6798         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6799         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6800
6801         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6802         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6803
6804         /* Now find out if the whole streams are re-read, or just the last active value for the
6805          * vertices is used.
6806          */
6807         hr = IDirect3DDevice9_BeginScene(device);
6808         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6809         if(SUCCEEDED(hr))
6810         {
6811             float quad1_modified[] =  {
6812                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6813                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6814                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6815                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6816             };
6817             float quad2_modified[] =  {
6818                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6819                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6820                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6821                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6822             };
6823
6824             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6825             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6826
6827             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6828             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6829             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6830             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6831
6832             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6833             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6834             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6835             if(i == 3 || i == 2) {
6836                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6837             } else if(i == 1) {
6838                 /* Succeeds or fails, depending on SW or HW vertex processing */
6839                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6840             }
6841
6842             hr = IDirect3DDevice9_EndScene(device);
6843             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6844         }
6845
6846         color = getPixelColor(device, 480, 350);
6847         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6848          * as well.
6849          *
6850          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6851          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6852          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6853          * refrast's result.
6854          *
6855          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6856          */
6857         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6858            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6859
6860         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6861         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6862
6863         IDirect3DDevice9_SetVertexShader(device, NULL);
6864         IDirect3DDevice9_SetPixelShader(device, NULL);
6865         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6866
6867         IDirect3DVertexShader9_Release(swapped_shader);
6868     }
6869
6870     for(i = 1; i <= 3; i++) {
6871         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6872         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6873         if(i == 3) {
6874             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6875             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6876             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6877             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6878             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6879             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6880         } else if(i == 2){
6881             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6882             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6883             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6884             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6885         } else if(i == 1) {
6886             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6887             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6888             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6889             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6890         }
6891
6892         hr = IDirect3DDevice9_BeginScene(device);
6893         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6894         if(SUCCEEDED(hr))
6895         {
6896             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6897             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6898             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6899             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6900             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6901             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6902
6903             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6904             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6905
6906             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6907             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6908             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6909             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6910             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6911             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6912
6913             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6914             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6915             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6916             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6917             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6918             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6919
6920             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6921             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6922             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6923             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6924
6925             hr = IDirect3DDevice9_EndScene(device);
6926             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6927         }
6928         IDirect3DDevice9_SetVertexShader(device, NULL);
6929         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6930         IDirect3DDevice9_SetPixelShader(device, NULL);
6931
6932         color = getPixelColor(device, 160, 360);
6933         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6934            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6935         color = getPixelColor(device, 480, 360);
6936         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6937            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6938         color = getPixelColor(device, 160, 120);
6939         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6940            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6941         color = getPixelColor(device, 480, 160);
6942         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6943            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6944
6945         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6946         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6947
6948         IDirect3DVertexShader9_Release(texcoord_color_shader);
6949         IDirect3DVertexShader9_Release(color_color_shader);
6950     }
6951
6952     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6953     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6954     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6955     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6956
6957     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6958     IDirect3DVertexDeclaration9_Release(decl_color_color);
6959     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6960     IDirect3DVertexDeclaration9_Release(decl_color_float);
6961
6962     IDirect3DPixelShader9_Release(ps);
6963 }
6964
6965 static void srgbtexture_test(IDirect3DDevice9 *device)
6966 {
6967     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6968      * texture stage state to render a quad using that texture.  The resulting
6969      * color components should be 0x36 (~ 0.21), per this formula:
6970      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6971      * This is true where srgb_color > 0.04045. */
6972     struct IDirect3DTexture9 *texture = NULL;
6973     struct IDirect3DSurface9 *surface = NULL;
6974     IDirect3D9 *d3d = NULL;
6975     HRESULT hr;
6976     D3DLOCKED_RECT lr;
6977     DWORD color;
6978     float quad[] = {
6979         -1.0,       1.0,       0.0,     0.0,    0.0,
6980          1.0,       1.0,       0.0,     1.0,    0.0,
6981         -1.0,      -1.0,       0.0,     0.0,    1.0,
6982          1.0,      -1.0,       0.0,     1.0,    1.0,
6983     };
6984
6985
6986     memset(&lr, 0, sizeof(lr));
6987     IDirect3DDevice9_GetDirect3D(device, &d3d);
6988     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6989                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6990                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6991         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6992         goto out;
6993     }
6994
6995     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6996                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6997                                         &texture, NULL);
6998     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6999     if(!texture) {
7000         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
7001         goto out;
7002     }
7003     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7004     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
7005
7006     fill_surface(surface, 0xff7f7f7f);
7007     IDirect3DSurface9_Release(surface);
7008
7009     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7010     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7011     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7012     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
7013
7014     hr = IDirect3DDevice9_BeginScene(device);
7015     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7016     if(SUCCEEDED(hr))
7017     {
7018         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
7019         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
7020
7021         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7022         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7023
7024
7025         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
7026         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
7027
7028         hr = IDirect3DDevice9_EndScene(device);
7029         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7030     }
7031
7032     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7033     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
7034     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
7035     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
7036
7037     color = getPixelColor(device, 320, 240);
7038     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
7039
7040     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7041     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7042
7043 out:
7044     if(texture) IDirect3DTexture9_Release(texture);
7045     IDirect3D9_Release(d3d);
7046 }
7047
7048 static void shademode_test(IDirect3DDevice9 *device)
7049 {
7050     /* Render a quad and try all of the different fixed function shading models. */
7051     struct IDirect3DVertexBuffer9 *vb_strip = NULL;
7052     struct IDirect3DVertexBuffer9 *vb_list = NULL;
7053     HRESULT hr;
7054     DWORD color0, color1;
7055     DWORD color0_gouraud = 0, color1_gouraud = 0;
7056     DWORD shademode = D3DSHADE_FLAT;
7057     DWORD primtype = D3DPT_TRIANGLESTRIP;
7058     LPVOID data = NULL;
7059     UINT i, j;
7060     struct vertex quad_strip[] =
7061     {
7062         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
7063         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
7064         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
7065         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
7066     };
7067     struct vertex quad_list[] =
7068     {
7069         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
7070         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
7071         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
7072
7073         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
7074         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
7075         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
7076     };
7077
7078     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
7079                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
7080     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7081     if (FAILED(hr)) goto bail;
7082
7083     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
7084                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
7085     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7086     if (FAILED(hr)) goto bail;
7087
7088     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7089     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7090
7091     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7092     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7093
7094     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
7095     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7096     memcpy(data, quad_strip, sizeof(quad_strip));
7097     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
7098     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7099
7100     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
7101     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7102     memcpy(data, quad_list, sizeof(quad_list));
7103     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
7104     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7105
7106     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
7107      * the color fixups we have to do for FLAT shading will be dependent on that. */
7108     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
7109     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7110
7111     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
7112     for (j=0; j<2; j++) {
7113
7114         /* Inner loop just changes the D3DRS_SHADEMODE */
7115         for (i=0; i<3; i++) {
7116             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7117             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7118
7119             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
7120             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7121
7122             hr = IDirect3DDevice9_BeginScene(device);
7123             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7124             if(SUCCEEDED(hr))
7125             {
7126                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
7127                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
7128
7129                 hr = IDirect3DDevice9_EndScene(device);
7130                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7131             }
7132
7133             /* Sample two spots from the output */
7134             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
7135             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
7136             switch(shademode) {
7137                 case D3DSHADE_FLAT:
7138                     /* Should take the color of the first vertex of each triangle */
7139                     if (0)
7140                     {
7141                         /* This test depends on EXT_provoking_vertex being
7142                          * available. This extension is currently (20090810)
7143                          * not common enough to let the test fail if it isn't
7144                          * present. */
7145                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
7146                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
7147                     }
7148                     shademode = D3DSHADE_GOURAUD;
7149                     break;
7150                 case D3DSHADE_GOURAUD:
7151                     /* Should be an interpolated blend */
7152
7153                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7154                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
7155                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7156                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
7157
7158                     color0_gouraud = color0;
7159                     color1_gouraud = color1;
7160
7161                     shademode = D3DSHADE_PHONG;
7162                     break;
7163                 case D3DSHADE_PHONG:
7164                     /* Should be the same as GOURAUD, since no hardware implements this */
7165                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7166                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
7167                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7168                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7169
7170                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7171                             color0_gouraud, color0);
7172                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7173                             color1_gouraud, color1);
7174                     break;
7175             }
7176         }
7177
7178         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7179         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7180
7181         /* Now, do it all over again with a TRIANGLELIST */
7182         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7183         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7184         primtype = D3DPT_TRIANGLELIST;
7185         shademode = D3DSHADE_FLAT;
7186     }
7187
7188 bail:
7189     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7190     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7191     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7192     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7193
7194     if (vb_strip)
7195         IDirect3DVertexBuffer9_Release(vb_strip);
7196     if (vb_list)
7197         IDirect3DVertexBuffer9_Release(vb_list);
7198 }
7199
7200 static void alpha_test(IDirect3DDevice9 *device)
7201 {
7202     HRESULT hr;
7203     IDirect3DTexture9 *offscreenTexture;
7204     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7205     DWORD color;
7206
7207     struct vertex quad1[] =
7208     {
7209         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
7210         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
7211         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
7212         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
7213     };
7214     struct vertex quad2[] =
7215     {
7216         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
7217         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
7218         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
7219         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
7220     };
7221     static const float composite_quad[][5] = {
7222         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7223         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
7224         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7225         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
7226     };
7227
7228     /* Clear the render target with alpha = 0.5 */
7229     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7230     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7231
7232     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7233     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7234
7235     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7236     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7237     if(!backbuffer) {
7238         goto out;
7239     }
7240
7241     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7242     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7243     if(!offscreen) {
7244         goto out;
7245     }
7246
7247     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7248     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7249
7250     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7251     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7252     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7253     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7254     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7255     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7256     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7257     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7258     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7259     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7260
7261     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7262     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7263     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7264
7265         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7266         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7267         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7268         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7269         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7270         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7271         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7272
7273         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7274         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7275         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7276         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7277         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7278         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7279
7280         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7281          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7282          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7283         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7284         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7285         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7286         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7287
7288         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7289         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7290         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7291         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7292         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7293         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7294
7295         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7296         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7297         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7298         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7299         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7300         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7301
7302         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7303         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7304
7305         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7306          * Disable alpha blending for the final composition
7307          */
7308         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7309         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7310         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7311         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7312
7313         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7314         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7315         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7316         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7317         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7318         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7319
7320         hr = IDirect3DDevice9_EndScene(device);
7321         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7322     }
7323
7324     color = getPixelColor(device, 160, 360);
7325     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7326        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7327
7328     color = getPixelColor(device, 160, 120);
7329     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7330        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7331
7332     color = getPixelColor(device, 480, 360);
7333     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7334        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7335
7336     color = getPixelColor(device, 480, 120);
7337     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7338        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7339
7340     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7341
7342     out:
7343     /* restore things */
7344     if(backbuffer) {
7345         IDirect3DSurface9_Release(backbuffer);
7346     }
7347     if(offscreenTexture) {
7348         IDirect3DTexture9_Release(offscreenTexture);
7349     }
7350     if(offscreen) {
7351         IDirect3DSurface9_Release(offscreen);
7352     }
7353 }
7354
7355 struct vertex_shortcolor {
7356     float x, y, z;
7357     unsigned short r, g, b, a;
7358 };
7359 struct vertex_floatcolor {
7360     float x, y, z;
7361     float r, g, b, a;
7362 };
7363
7364 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7365 {
7366     HRESULT hr;
7367     BOOL s_ok, ub_ok, f_ok;
7368     DWORD color, size, i;
7369     void *data;
7370     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7371         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7372         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7373         D3DDECL_END()
7374     };
7375     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7376         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7377         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7378         D3DDECL_END()
7379     };
7380     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7381         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7382         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7383         D3DDECL_END()
7384     };
7385     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7386         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7387         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7388         D3DDECL_END()
7389     };
7390     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7391         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7392         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7393         D3DDECL_END()
7394     };
7395     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7396         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7397         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7398         D3DDECL_END()
7399     };
7400     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7401         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
7402         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7403         D3DDECL_END()
7404     };
7405     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7406     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7407     IDirect3DVertexBuffer9 *vb, *vb2;
7408     struct vertex quad1[] =                             /* D3DCOLOR */
7409     {
7410         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
7411         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7412         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
7413         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7414     };
7415     struct vertex quad2[] =                             /* UBYTE4N */
7416     {
7417         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7418         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
7419         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7420         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
7421     };
7422     struct vertex_shortcolor quad3[] =                  /* short */
7423     {
7424         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7425         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7426         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7427         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7428     };
7429     struct vertex_floatcolor quad4[] =
7430     {
7431         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7432         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7433         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7434         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7435     };
7436     DWORD colors[] = {
7437         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7438         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7439         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7440         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7441         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7442         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7443         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7444         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7445         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7446         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7447         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7448         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7449         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7450         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7451         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7452         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7453     };
7454     float quads[] = {
7455         -1.0,   -1.0,     0.1,
7456         -1.0,    0.0,     0.1,
7457          0.0,   -1.0,     0.1,
7458          0.0,    0.0,     0.1,
7459
7460          0.0,   -1.0,     0.1,
7461          0.0,    0.0,     0.1,
7462          1.0,   -1.0,     0.1,
7463          1.0,    0.0,     0.1,
7464
7465          0.0,    0.0,     0.1,
7466          0.0,    1.0,     0.1,
7467          1.0,    0.0,     0.1,
7468          1.0,    1.0,     0.1,
7469
7470         -1.0,    0.0,     0.1,
7471         -1.0,    1.0,     0.1,
7472          0.0,    0.0,     0.1,
7473          0.0,    1.0,     0.1
7474     };
7475     struct tvertex quad_transformed[] = {
7476        {  90,    110,     0.1,      2.0,        0x00ffff00},
7477        { 570,    110,     0.1,      2.0,        0x00ffff00},
7478        {  90,    300,     0.1,      2.0,        0x00ffff00},
7479        { 570,    300,     0.1,      2.0,        0x00ffff00}
7480     };
7481     D3DCAPS9 caps;
7482
7483     memset(&caps, 0, sizeof(caps));
7484     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7485     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7486
7487     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7488     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7489
7490     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7491     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7492     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7493     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7494     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7495     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7496     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7497         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7498         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7499         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7500         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7501     } else {
7502         trace("D3DDTCAPS_UBYTE4N not supported\n");
7503         dcl_ubyte_2 = NULL;
7504         dcl_ubyte = NULL;
7505     }
7506     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7507     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7508     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7509     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7510
7511     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7512     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7513                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7514     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7515
7516     hr = IDirect3DDevice9_BeginScene(device);
7517     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7518     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7519     if(SUCCEEDED(hr)) {
7520         if(dcl_color) {
7521             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7522             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7523             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7524             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7525         }
7526
7527         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7528          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7529          * using software vertex processing. Doh!
7530          */
7531         if(dcl_ubyte) {
7532             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7533             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7534             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7535             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7536             ub_ok = SUCCEEDED(hr);
7537         }
7538
7539         if(dcl_short) {
7540             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7541             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7542             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7543             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7544             s_ok = SUCCEEDED(hr);
7545         }
7546
7547         if(dcl_float) {
7548             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7549             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7550             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7551             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7552             f_ok = SUCCEEDED(hr);
7553         }
7554
7555         hr = IDirect3DDevice9_EndScene(device);
7556         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7557     }
7558
7559     if(dcl_short) {
7560         color = getPixelColor(device, 480, 360);
7561         ok(color == 0x000000ff || !s_ok,
7562            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7563     }
7564     if(dcl_ubyte) {
7565         color = getPixelColor(device, 160, 120);
7566         ok(color == 0x0000ffff || !ub_ok,
7567            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7568     }
7569     if(dcl_color) {
7570         color = getPixelColor(device, 160, 360);
7571         ok(color == 0x00ffff00,
7572            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7573     }
7574     if(dcl_float) {
7575         color = getPixelColor(device, 480, 120);
7576         ok(color == 0x00ff0000 || !f_ok,
7577            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7578     }
7579     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7580
7581     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7582      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7583      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7584      * whether the immediate mode code works
7585      */
7586     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7587     hr = IDirect3DDevice9_BeginScene(device);
7588     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7589     if(SUCCEEDED(hr)) {
7590         if(dcl_color) {
7591             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7592             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7593             memcpy(data, quad1, sizeof(quad1));
7594             hr = IDirect3DVertexBuffer9_Unlock(vb);
7595             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7596             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7597             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7598             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7599             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7600             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7601             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7602         }
7603
7604         if(dcl_ubyte) {
7605             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7606             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7607             memcpy(data, quad2, sizeof(quad2));
7608             hr = IDirect3DVertexBuffer9_Unlock(vb);
7609             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7610             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7611             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7612             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7613             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7614             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7615             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7616                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7617             ub_ok = SUCCEEDED(hr);
7618         }
7619
7620         if(dcl_short) {
7621             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7622             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7623             memcpy(data, quad3, sizeof(quad3));
7624             hr = IDirect3DVertexBuffer9_Unlock(vb);
7625             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7626             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7627             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7628             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7629             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7630             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7631             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7632                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7633             s_ok = SUCCEEDED(hr);
7634         }
7635
7636         if(dcl_float) {
7637             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7638             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7639             memcpy(data, quad4, sizeof(quad4));
7640             hr = IDirect3DVertexBuffer9_Unlock(vb);
7641             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7642             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7643             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7644             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7645             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7646             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7647             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7648                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7649             f_ok = SUCCEEDED(hr);
7650         }
7651
7652         hr = IDirect3DDevice9_EndScene(device);
7653         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7654     }
7655
7656     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7657     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7658     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7659     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7660
7661     if(dcl_short) {
7662         color = getPixelColor(device, 480, 360);
7663         ok(color == 0x000000ff || !s_ok,
7664            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7665     }
7666     if(dcl_ubyte) {
7667         color = getPixelColor(device, 160, 120);
7668         ok(color == 0x0000ffff || !ub_ok,
7669            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7670     }
7671     if(dcl_color) {
7672         color = getPixelColor(device, 160, 360);
7673         ok(color == 0x00ffff00,
7674            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7675     }
7676     if(dcl_float) {
7677         color = getPixelColor(device, 480, 120);
7678         ok(color == 0x00ff0000 || !f_ok,
7679            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7680     }
7681     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7682
7683     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7684     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7685
7686     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7687     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7688     memcpy(data, quad_transformed, sizeof(quad_transformed));
7689     hr = IDirect3DVertexBuffer9_Unlock(vb);
7690     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7691
7692     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7693     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7694
7695     hr = IDirect3DDevice9_BeginScene(device);
7696     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7697     if(SUCCEEDED(hr)) {
7698         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7699         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7700         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7701         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7702
7703         hr = IDirect3DDevice9_EndScene(device);
7704         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7705     }
7706
7707     color = getPixelColor(device, 88, 108);
7708     ok(color == 0x000000ff,
7709        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7710     color = getPixelColor(device, 92, 108);
7711     ok(color == 0x000000ff,
7712        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7713     color = getPixelColor(device, 88, 112);
7714     ok(color == 0x000000ff,
7715        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7716     color = getPixelColor(device, 92, 112);
7717     ok(color == 0x00ffff00,
7718        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7719
7720     color = getPixelColor(device, 568, 108);
7721     ok(color == 0x000000ff,
7722        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7723     color = getPixelColor(device, 572, 108);
7724     ok(color == 0x000000ff,
7725        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7726     color = getPixelColor(device, 568, 112);
7727     ok(color == 0x00ffff00,
7728        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7729     color = getPixelColor(device, 572, 112);
7730     ok(color == 0x000000ff,
7731        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7732
7733     color = getPixelColor(device, 88, 298);
7734     ok(color == 0x000000ff,
7735        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7736     color = getPixelColor(device, 92, 298);
7737     ok(color == 0x00ffff00,
7738        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7739     color = getPixelColor(device, 88, 302);
7740     ok(color == 0x000000ff,
7741        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7742     color = getPixelColor(device, 92, 302);
7743     ok(color == 0x000000ff,
7744        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7745
7746     color = getPixelColor(device, 568, 298);
7747     ok(color == 0x00ffff00,
7748        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7749     color = getPixelColor(device, 572, 298);
7750     ok(color == 0x000000ff,
7751        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7752     color = getPixelColor(device, 568, 302);
7753     ok(color == 0x000000ff,
7754        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7755     color = getPixelColor(device, 572, 302);
7756     ok(color == 0x000000ff,
7757        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7758
7759     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7760
7761     /* This test is pointless without those two declarations: */
7762     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7763         skip("color-ubyte switching test declarations aren't supported\n");
7764         goto out;
7765     }
7766
7767     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7768     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7769     memcpy(data, quads, sizeof(quads));
7770     hr = IDirect3DVertexBuffer9_Unlock(vb);
7771     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7772     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7773                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7774     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7775     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7776     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7777     memcpy(data, colors, sizeof(colors));
7778     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7779     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7780
7781     for(i = 0; i < 2; i++) {
7782         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7783         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7784
7785         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7786         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7787         if(i == 0) {
7788             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7789         } else {
7790             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7791         }
7792         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7793
7794         hr = IDirect3DDevice9_BeginScene(device);
7795         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7796         ub_ok = FALSE;
7797         if(SUCCEEDED(hr)) {
7798             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7799             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7800             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7801             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7802                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7803             ub_ok = SUCCEEDED(hr);
7804
7805             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7806             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7807             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7808             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7809
7810             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7811             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7812             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7813             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7814                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7815             ub_ok = (SUCCEEDED(hr) && ub_ok);
7816
7817             hr = IDirect3DDevice9_EndScene(device);
7818             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7819         }
7820
7821         if(i == 0) {
7822             color = getPixelColor(device, 480, 360);
7823             ok(color == 0x00ff0000,
7824                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7825             color = getPixelColor(device, 160, 120);
7826             ok(color == 0x00ffffff,
7827                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7828             color = getPixelColor(device, 160, 360);
7829             ok(color == 0x000000ff || !ub_ok,
7830                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7831             color = getPixelColor(device, 480, 120);
7832             ok(color == 0x000000ff || !ub_ok,
7833                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7834         } else {
7835             color = getPixelColor(device, 480, 360);
7836             ok(color == 0x000000ff,
7837                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7838             color = getPixelColor(device, 160, 120);
7839             ok(color == 0x00ffffff,
7840                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7841             color = getPixelColor(device, 160, 360);
7842             ok(color == 0x00ff0000 || !ub_ok,
7843                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7844             color = getPixelColor(device, 480, 120);
7845             ok(color == 0x00ff0000 || !ub_ok,
7846                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7847         }
7848         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7849     }
7850
7851     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7852     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7853     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7854     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7855     IDirect3DVertexBuffer9_Release(vb2);
7856
7857     out:
7858     IDirect3DVertexBuffer9_Release(vb);
7859     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7860     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7861     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7862     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7863     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7864     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7865     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7866 }
7867
7868 struct vertex_float16color {
7869     float x, y, z;
7870     DWORD c1, c2;
7871 };
7872
7873 static void test_vshader_float16(IDirect3DDevice9 *device)
7874 {
7875     HRESULT hr;
7876     DWORD color;
7877     void *data;
7878     static const D3DVERTEXELEMENT9 decl_elements[] = {
7879         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7880         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7881         D3DDECL_END()
7882     };
7883     IDirect3DVertexDeclaration9 *vdecl = NULL;
7884     IDirect3DVertexBuffer9 *buffer = NULL;
7885     IDirect3DVertexShader9 *shader;
7886     DWORD shader_code[] = {
7887         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7888         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7889         0x90e40001, 0x0000ffff
7890     };
7891     struct vertex_float16color quad[] = {
7892         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7893         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7894         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7895         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7896
7897         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7898         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7899         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7900         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7901
7902         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7903         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7904         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7905         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7906
7907         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7908         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7909         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7910         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7911     };
7912
7913     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7914     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7915
7916     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7917     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7918     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7919     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7920     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7921     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7922
7923     hr = IDirect3DDevice9_BeginScene(device);
7924     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7925     if(SUCCEEDED(hr)) {
7926         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7927         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7928         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7929         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7930         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7931         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7932         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7933         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7934         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7935         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7936
7937         hr = IDirect3DDevice9_EndScene(device);
7938         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7939     }
7940     color = getPixelColor(device, 480, 360);
7941     ok(color == 0x00ff0000,
7942        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7943     color = getPixelColor(device, 160, 120);
7944     ok(color == 0x00000000,
7945        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7946     color = getPixelColor(device, 160, 360);
7947     ok(color == 0x0000ff00,
7948        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7949     color = getPixelColor(device, 480, 120);
7950     ok(color == 0x000000ff,
7951        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7952     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7953
7954     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7955     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7956
7957     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7958                                              D3DPOOL_MANAGED, &buffer, NULL);
7959     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7960     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7961     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7962     memcpy(data, quad, sizeof(quad));
7963     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7964     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7965     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7966     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7967
7968     hr = IDirect3DDevice9_BeginScene(device);
7969     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7970     if(SUCCEEDED(hr)) {
7971             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7972             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7973             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7974             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7975             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7976             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7977             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7978             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7979
7980             hr = IDirect3DDevice9_EndScene(device);
7981             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7982     }
7983
7984     color = getPixelColor(device, 480, 360);
7985     ok(color == 0x00ff0000,
7986        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7987     color = getPixelColor(device, 160, 120);
7988     ok(color == 0x00000000,
7989        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7990     color = getPixelColor(device, 160, 360);
7991     ok(color == 0x0000ff00,
7992        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7993     color = getPixelColor(device, 480, 120);
7994     ok(color == 0x000000ff,
7995        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7996     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7997
7998     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7999     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
8000     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8001     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8002     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8003     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8004
8005     IDirect3DVertexDeclaration9_Release(vdecl);
8006     IDirect3DVertexShader9_Release(shader);
8007     IDirect3DVertexBuffer9_Release(buffer);
8008 }
8009
8010 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
8011 {
8012     D3DCAPS9 caps;
8013     IDirect3DTexture9 *texture;
8014     HRESULT hr;
8015     D3DLOCKED_RECT rect;
8016     unsigned int x, y;
8017     DWORD *dst, color;
8018     const float quad[] = {
8019         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
8020          1.0,   -1.0,   0.1,    1.2,   -0.2,
8021         -1.0,    1.0,   0.1,   -0.2,    1.2,
8022          1.0,    1.0,   0.1,    1.2,    1.2
8023     };
8024     memset(&caps, 0, sizeof(caps));
8025
8026     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8027     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8028     if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
8029     {
8030         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
8031         ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
8032                 "Card has conditional NP2 support without power of two restriction set\n");
8033     }
8034     else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
8035     {
8036         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
8037         return;
8038     }
8039     else
8040     {
8041         skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
8042         return;
8043     }
8044
8045     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8046     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8047
8048     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
8049     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8050
8051     memset(&rect, 0, sizeof(rect));
8052     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
8053     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8054     for(y = 0; y < 10; y++) {
8055         for(x = 0; x < 10; x++) {
8056             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
8057             if(x == 0 || x == 9 || y == 0 || y == 9) {
8058                 *dst = 0x00ff0000;
8059             } else {
8060                 *dst = 0x000000ff;
8061             }
8062         }
8063     }
8064     hr = IDirect3DTexture9_UnlockRect(texture, 0);
8065     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8066
8067     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8068     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8069     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
8070     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8071     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
8072     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8073     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8074     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8075
8076     hr = IDirect3DDevice9_BeginScene(device);
8077     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8078     if(SUCCEEDED(hr)) {
8079         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8080         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8081
8082         hr = IDirect3DDevice9_EndScene(device);
8083         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8084     }
8085
8086     color = getPixelColor(device,    1,  1);
8087     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
8088     color = getPixelColor(device, 639, 479);
8089     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
8090
8091     color = getPixelColor(device, 135, 101);
8092     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
8093     color = getPixelColor(device, 140, 101);
8094     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
8095     color = getPixelColor(device, 135, 105);
8096     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
8097     color = getPixelColor(device, 140, 105);
8098     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
8099
8100     color = getPixelColor(device, 135, 376);
8101     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
8102     color = getPixelColor(device, 140, 376);
8103     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
8104     color = getPixelColor(device, 135, 379);
8105     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
8106     color = getPixelColor(device, 140, 379);
8107     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
8108
8109     color = getPixelColor(device, 500, 101);
8110     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
8111     color = getPixelColor(device, 504, 101);
8112     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
8113     color = getPixelColor(device, 500, 105);
8114     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
8115     color = getPixelColor(device, 504, 105);
8116     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
8117
8118     color = getPixelColor(device, 500, 376);
8119     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
8120     color = getPixelColor(device, 504, 376);
8121     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
8122     color = getPixelColor(device, 500, 380);
8123     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
8124     color = getPixelColor(device, 504, 380);
8125     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
8126
8127     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8128
8129     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8130     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8131     IDirect3DTexture9_Release(texture);
8132 }
8133
8134 static void vFace_register_test(IDirect3DDevice9 *device)
8135 {
8136     HRESULT hr;
8137     DWORD color;
8138     const DWORD shader_code[] = {
8139         0xffff0300,                                                             /* ps_3_0                     */
8140         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8141         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
8142         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
8143         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
8144         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
8145         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8146         0x0000ffff                                                              /* END                        */
8147     };
8148     const DWORD vshader_code[] = {
8149         0xfffe0300,                                                             /* vs_3_0               */
8150         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8151         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8152         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8153         0x0000ffff                                                              /* end                  */
8154     };
8155     IDirect3DPixelShader9 *shader;
8156     IDirect3DVertexShader9 *vshader;
8157     IDirect3DTexture9 *texture;
8158     IDirect3DSurface9 *surface, *backbuffer;
8159     const float quad[] = {
8160         -1.0,   -1.0,   0.1,
8161          1.0,   -1.0,   0.1,
8162         -1.0,    0.0,   0.1,
8163
8164          1.0,   -1.0,   0.1,
8165          1.0,    0.0,   0.1,
8166         -1.0,    0.0,   0.1,
8167
8168         -1.0,    0.0,   0.1,
8169         -1.0,    1.0,   0.1,
8170          1.0,    0.0,   0.1,
8171
8172          1.0,    0.0,   0.1,
8173         -1.0,    1.0,   0.1,
8174          1.0,    1.0,   0.1,
8175     };
8176     const float blit[] = {
8177          0.0,   -1.0,   0.1,    0.0,    0.0,
8178          1.0,   -1.0,   0.1,    1.0,    0.0,
8179          0.0,    1.0,   0.1,    0.0,    1.0,
8180          1.0,    1.0,   0.1,    1.0,    1.0,
8181     };
8182
8183     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8184     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8185     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8186     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8187     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8188     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8189     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8190     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8191     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8192     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8193     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8194     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8195     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8196     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8197     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8198     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8199
8200     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8201     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8202
8203     hr = IDirect3DDevice9_BeginScene(device);
8204     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8205     if(SUCCEEDED(hr)) {
8206         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8207         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8208         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8209         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8210         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8211         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8212         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8213         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8214         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8215         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8216         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8217
8218         /* Blit the texture onto the back buffer to make it visible */
8219         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8220         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
8221         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8222         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8223         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8224         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8225         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8226         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8227         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8228         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8229         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8230         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8231
8232         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8233         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8234
8235         hr = IDirect3DDevice9_EndScene(device);
8236         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8237     }
8238
8239     color = getPixelColor(device, 160, 360);
8240     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8241     color = getPixelColor(device, 160, 120);
8242     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8243     color = getPixelColor(device, 480, 360);
8244     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8245     color = getPixelColor(device, 480, 120);
8246     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8247     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8248     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8249
8250     IDirect3DDevice9_SetTexture(device, 0, NULL);
8251     IDirect3DPixelShader9_Release(shader);
8252     IDirect3DVertexShader9_Release(vshader);
8253     IDirect3DSurface9_Release(surface);
8254     IDirect3DSurface9_Release(backbuffer);
8255     IDirect3DTexture9_Release(texture);
8256 }
8257
8258 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8259 {
8260     HRESULT hr;
8261     DWORD color;
8262     int i;
8263     D3DCAPS9 caps;
8264     BOOL L6V5U5_supported = FALSE;
8265     IDirect3DTexture9 *tex1, *tex2;
8266     D3DLOCKED_RECT locked_rect;
8267
8268     static const float quad[][7] = {
8269         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8270         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8271         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8272         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8273     };
8274
8275     static const D3DVERTEXELEMENT9 decl_elements[] = {
8276         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8277         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8278         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8279         D3DDECL_END()
8280     };
8281
8282     /* use asymmetric matrix to test loading */
8283     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8284     float scale, offset;
8285
8286     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8287     IDirect3DTexture9           *texture            = NULL;
8288
8289     memset(&caps, 0, sizeof(caps));
8290     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8291     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8292     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8293         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8294         return;
8295     } else {
8296         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8297          * They report that it is not supported, but after that bump mapping works properly. So just test
8298          * if the format is generally supported, and check the BUMPENVMAP flag
8299          */
8300         IDirect3D9 *d3d9;
8301
8302         IDirect3DDevice9_GetDirect3D(device, &d3d9);
8303         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8304                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8305         L6V5U5_supported = SUCCEEDED(hr);
8306         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8307                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8308         IDirect3D9_Release(d3d9);
8309         if(FAILED(hr)) {
8310             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8311             return;
8312         }
8313     }
8314
8315     /* Generate the textures */
8316     generate_bumpmap_textures(device);
8317
8318     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8319     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8320     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8321     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8322     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8323     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8324     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8325     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8326
8327     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8328     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8329     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8330     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8331     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8332     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8333
8334     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8335     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8336     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8337     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8338     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8339     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8340
8341     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8342     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8343
8344     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8345     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8346
8347     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8348     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8349
8350
8351     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8352     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8353     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8354     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8355
8356     hr = IDirect3DDevice9_BeginScene(device);
8357     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8358
8359     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8360     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8361
8362     hr = IDirect3DDevice9_EndScene(device);
8363     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8364
8365     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8366      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8367      * But since testing the color match is not the purpose of the test don't be too picky
8368      */
8369     color = getPixelColor(device, 320-32, 240);
8370     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8371     color = getPixelColor(device, 320+32, 240);
8372     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8373     color = getPixelColor(device, 320, 240-32);
8374     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8375     color = getPixelColor(device, 320, 240+32);
8376     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8377     color = getPixelColor(device, 320, 240);
8378     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8379     color = getPixelColor(device, 320+32, 240+32);
8380     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8381     color = getPixelColor(device, 320-32, 240+32);
8382     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8383     color = getPixelColor(device, 320+32, 240-32);
8384     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8385     color = getPixelColor(device, 320-32, 240-32);
8386     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8387     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8388     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8389
8390     for(i = 0; i < 2; i++) {
8391         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8392         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8393         IDirect3DTexture9_Release(texture); /* For the GetTexture */
8394         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8395         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8396         IDirect3DTexture9_Release(texture); /* To destroy it */
8397     }
8398
8399     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8400         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8401         goto cleanup;
8402     }
8403     if(L6V5U5_supported == FALSE) {
8404         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8405         goto cleanup;
8406     }
8407
8408     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8409     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8410     /* This test only tests the luminance part. The bumpmapping part was already tested above and
8411      * would only make this test more complicated
8412      */
8413     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8414     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8415     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8416     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8417
8418     memset(&locked_rect, 0, sizeof(locked_rect));
8419     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8420     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8421     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8422     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8423     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8424
8425     memset(&locked_rect, 0, sizeof(locked_rect));
8426     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8427     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8428     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8429     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8430     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8431
8432     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8433     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8434     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8435     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8436
8437     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8438     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8439     scale = 2.0;
8440     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8441     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8442     offset = 0.1;
8443     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8444     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8445
8446     hr = IDirect3DDevice9_BeginScene(device);
8447     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8448     if(SUCCEEDED(hr)) {
8449         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8450         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8451         hr = IDirect3DDevice9_EndScene(device);
8452         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8453     }
8454
8455     color = getPixelColor(device, 320, 240);
8456     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
8457      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
8458      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8459      */
8460     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8461     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8462     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8463
8464     /* Check a result scale factor > 1.0 */
8465     scale = 10;
8466     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8467     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8468     offset = 10;
8469     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8470     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8471
8472     hr = IDirect3DDevice9_BeginScene(device);
8473     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8474     if(SUCCEEDED(hr)) {
8475         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8476         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8477         hr = IDirect3DDevice9_EndScene(device);
8478         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8479     }
8480     color = getPixelColor(device, 320, 240);
8481     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8482     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8483     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8484
8485     /* Check clamping in the scale factor calculation */
8486     scale = 1000;
8487     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8488     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8489     offset = -1;
8490     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8491     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8492
8493     hr = IDirect3DDevice9_BeginScene(device);
8494     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8495     if(SUCCEEDED(hr)) {
8496         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8497         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8498         hr = IDirect3DDevice9_EndScene(device);
8499         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8500     }
8501     color = getPixelColor(device, 320, 240);
8502     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8503     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8504     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8505
8506     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8507     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8508     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8509     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8510
8511     IDirect3DTexture9_Release(tex1);
8512     IDirect3DTexture9_Release(tex2);
8513
8514 cleanup:
8515     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8516     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8517     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8518     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8519
8520     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8521     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8522     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8523 }
8524
8525 static void stencil_cull_test(IDirect3DDevice9 *device) {
8526     HRESULT hr;
8527     IDirect3DSurface9 *depthstencil = NULL;
8528     D3DSURFACE_DESC desc;
8529     float quad1[] = {
8530         -1.0,   -1.0,   0.1,
8531          0.0,   -1.0,   0.1,
8532         -1.0,    0.0,   0.1,
8533          0.0,    0.0,   0.1,
8534     };
8535     float quad2[] = {
8536          0.0,   -1.0,   0.1,
8537          1.0,   -1.0,   0.1,
8538          0.0,    0.0,   0.1,
8539          1.0,    0.0,   0.1,
8540     };
8541     float quad3[] = {
8542         0.0,    0.0,   0.1,
8543         1.0,    0.0,   0.1,
8544         0.0,    1.0,   0.1,
8545         1.0,    1.0,   0.1,
8546     };
8547     float quad4[] = {
8548         -1.0,    0.0,   0.1,
8549          0.0,    0.0,   0.1,
8550         -1.0,    1.0,   0.1,
8551          0.0,    1.0,   0.1,
8552     };
8553     struct vertex painter[] = {
8554        {-1.0,   -1.0,   0.0,    0x00000000},
8555        { 1.0,   -1.0,   0.0,    0x00000000},
8556        {-1.0,    1.0,   0.0,    0x00000000},
8557        { 1.0,    1.0,   0.0,    0x00000000},
8558     };
8559     WORD indices_cw[]  = {0, 1, 3};
8560     WORD indices_ccw[] = {0, 2, 3};
8561     unsigned int i;
8562     DWORD color;
8563
8564     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8565     if(depthstencil == NULL) {
8566         skip("No depth stencil buffer\n");
8567         return;
8568     }
8569     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8570     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8571     IDirect3DSurface9_Release(depthstencil);
8572     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8573         skip("No 4 or 8 bit stencil surface\n");
8574         return;
8575     }
8576
8577     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8578     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8579     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8580     ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
8581
8582     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8583     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8584     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8585     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8586     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8587     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8588     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8589     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8590
8591     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8592     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8593     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8594     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8595     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8596     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8597
8598     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8599     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8600     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8601     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8602
8603     /* First pass: Fill the stencil buffer with some values... */
8604     hr = IDirect3DDevice9_BeginScene(device);
8605     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8606     if(SUCCEEDED(hr))
8607     {
8608         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8609         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8610         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8611                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8612         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8613         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8614                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8615         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8616
8617         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8618         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8619         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8620         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8621         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8622                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8623         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8624         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8625                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8626         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8627
8628         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8629         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8630         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8631                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8632         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8633         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8634                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8635         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8636
8637         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8638         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8639         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8640                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8641         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8642         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8643                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8644         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8645
8646         hr = IDirect3DDevice9_EndScene(device);
8647         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8648     }
8649
8650     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8651     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8652     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8653     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8654     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8655     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8656     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8657     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8658     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8659     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8660     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8661     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8662
8663     /* 2nd pass: Make the stencil values visible */
8664     hr = IDirect3DDevice9_BeginScene(device);
8665     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8666     if(SUCCEEDED(hr))
8667     {
8668         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8669         ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8670         for (i = 0; i < 16; ++i)
8671         {
8672             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8673             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8674
8675             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8676             painter[1].diffuse = (i * 16);
8677             painter[2].diffuse = (i * 16);
8678             painter[3].diffuse = (i * 16);
8679             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8680             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8681         }
8682         hr = IDirect3DDevice9_EndScene(device);
8683         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8684     }
8685
8686     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8687     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8688
8689     color = getPixelColor(device, 160, 420);
8690     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8691     color = getPixelColor(device, 160, 300);
8692     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8693
8694     color = getPixelColor(device, 480, 420);
8695     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8696     color = getPixelColor(device, 480, 300);
8697     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8698
8699     color = getPixelColor(device, 160, 180);
8700     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8701     color = getPixelColor(device, 160, 60);
8702     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8703
8704     color = getPixelColor(device, 480, 180);
8705     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8706     color = getPixelColor(device, 480, 60);
8707     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8708
8709     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8710     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8711 }
8712
8713 static void vpos_register_test(IDirect3DDevice9 *device)
8714 {
8715     HRESULT hr;
8716     DWORD color;
8717     const DWORD shader_code[] = {
8718     0xffff0300,                                                             /* ps_3_0                     */
8719     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8720     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8721     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8722     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8723     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8724     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8725     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8726     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8727     0x0000ffff                                                              /* end                        */
8728     };
8729     const DWORD shader_frac_code[] = {
8730     0xffff0300,                                                             /* ps_3_0                     */
8731     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8732     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8733     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8734     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8735     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8736     0x0000ffff                                                              /* end                        */
8737     };
8738     const DWORD vshader_code[] = {
8739         0xfffe0300,                                                             /* vs_3_0               */
8740         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8741         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8742         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8743         0x0000ffff                                                              /* end                  */
8744     };
8745     IDirect3DVertexShader9 *vshader;
8746     IDirect3DPixelShader9 *shader, *shader_frac;
8747     IDirect3DSurface9 *surface = NULL, *backbuffer;
8748     const float quad[] = {
8749         -1.0,   -1.0,   0.1,    0.0,    0.0,
8750          1.0,   -1.0,   0.1,    1.0,    0.0,
8751         -1.0,    1.0,   0.1,    0.0,    1.0,
8752          1.0,    1.0,   0.1,    1.0,    1.0,
8753     };
8754     D3DLOCKED_RECT lr;
8755     float constant[4] = {1.0, 0.0, 320, 240};
8756     DWORD *pos;
8757
8758     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8759     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8760     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8761     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8762     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8763     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8764     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8765     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8766     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8767     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8768     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8769     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8770     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8771     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8772     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8773     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8774
8775     hr = IDirect3DDevice9_BeginScene(device);
8776     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8777     if(SUCCEEDED(hr)) {
8778         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8779         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8780         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8781         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8782         hr = IDirect3DDevice9_EndScene(device);
8783         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8784     }
8785
8786     /* This has to be pixel exact */
8787     color = getPixelColor(device, 319, 239);
8788     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8789     color = getPixelColor(device, 320, 239);
8790     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8791     color = getPixelColor(device, 319, 240);
8792     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8793     color = getPixelColor(device, 320, 240);
8794     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8795     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8796
8797     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8798                                              &surface, NULL);
8799     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8800     hr = IDirect3DDevice9_BeginScene(device);
8801     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8802     if(SUCCEEDED(hr)) {
8803         constant[2] = 16; constant[3] = 16;
8804         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8805         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8806         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8807         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8808         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8809         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8810         hr = IDirect3DDevice9_EndScene(device);
8811         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8812     }
8813     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8814     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8815
8816     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8817     color = *pos & 0x00ffffff;
8818     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8819     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8820     color = *pos & 0x00ffffff;
8821     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8822     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8823     color = *pos & 0x00ffffff;
8824     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8825     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8826     color = *pos & 0x00ffffff;
8827     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8828
8829     hr = IDirect3DSurface9_UnlockRect(surface);
8830     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8831
8832     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8833      * have full control over the multisampling setting inside this test
8834      */
8835     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8836     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8837     hr = IDirect3DDevice9_BeginScene(device);
8838     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8839     if(SUCCEEDED(hr)) {
8840         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8841         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8842         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8843         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8844         hr = IDirect3DDevice9_EndScene(device);
8845         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8846     }
8847     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8848     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8849
8850     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8851     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8852
8853     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8854     color = *pos & 0x00ffffff;
8855     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8856
8857     hr = IDirect3DSurface9_UnlockRect(surface);
8858     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8859
8860     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8861     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8862     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8863     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8864     IDirect3DPixelShader9_Release(shader);
8865     IDirect3DPixelShader9_Release(shader_frac);
8866     IDirect3DVertexShader9_Release(vshader);
8867     if(surface) IDirect3DSurface9_Release(surface);
8868     IDirect3DSurface9_Release(backbuffer);
8869 }
8870
8871 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8872 {
8873     D3DCOLOR color;
8874
8875     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8876     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8877     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8878     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8879     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8880
8881     ++r;
8882     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8883     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8884     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8885     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8886     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8887
8888     return TRUE;
8889 }
8890
8891 static void pointsize_test(IDirect3DDevice9 *device)
8892 {
8893     HRESULT hr;
8894     D3DCAPS9 caps;
8895     D3DMATRIX matrix;
8896     D3DMATRIX identity;
8897     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8898     DWORD color;
8899     IDirect3DSurface9 *rt, *backbuffer;
8900     IDirect3DTexture9 *tex1, *tex2;
8901     RECT rect = {0, 0, 128, 128};
8902     D3DLOCKED_RECT lr;
8903     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8904                                 0x00000000, 0x00000000};
8905     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8906                                 0x00000000, 0x0000ff00};
8907
8908     const float vertices[] = {
8909         64,     64,     0.1,
8910         128,    64,     0.1,
8911         192,    64,     0.1,
8912         256,    64,     0.1,
8913         320,    64,     0.1,
8914         384,    64,     0.1,
8915         448,    64,     0.1,
8916         512,    64,     0.1,
8917     };
8918
8919     /* 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 */
8920     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;
8921     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;
8922     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;
8923     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;
8924
8925     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;
8926     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;
8927     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;
8928     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;
8929
8930     memset(&caps, 0, sizeof(caps));
8931     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8932     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8933     if(caps.MaxPointSize < 32.0) {
8934         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8935         return;
8936     }
8937
8938     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8939     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8940     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8941     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8942     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8943     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8944     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8945     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8946
8947     hr = IDirect3DDevice9_BeginScene(device);
8948     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8949     if (SUCCEEDED(hr))
8950     {
8951         ptsize = 15.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[0], sizeof(float) * 3);
8955         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8956
8957         ptsize = 31.0;
8958         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8959         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8960         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8961         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8962
8963         ptsize = 30.75;
8964         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8965         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8966         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8967         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8968
8969         if (caps.MaxPointSize >= 63.0)
8970         {
8971             ptsize = 63.0;
8972             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8973             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8974             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8975             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8976
8977             ptsize = 62.75;
8978             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8979             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8980             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8981             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8982         }
8983
8984         ptsize = 1.0;
8985         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8986         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8987         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8988         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8989
8990         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8991         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8992         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8993         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8994
8995         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8996         ptsize = 15.0;
8997         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8998         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8999         ptsize = 1.0;
9000         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
9001         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9002         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
9003         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9004
9005         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
9006         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9007
9008         /* pointsize < pointsize_min < pointsize_max?
9009          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
9010         ptsize = 1.0;
9011         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9012         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9013         ptsize = 15.0;
9014         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
9015         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9016         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
9017         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9018
9019         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
9020         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9021
9022         hr = IDirect3DDevice9_EndScene(device);
9023         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
9024     }
9025
9026     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
9027     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
9028     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
9029
9030     if (caps.MaxPointSize >= 63.0)
9031     {
9032         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
9033         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
9034     }
9035
9036     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
9037     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
9038     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
9039     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
9040     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
9041
9042     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9043
9044     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
9045      * generates texture coordinates for the point(result: Yes, it does)
9046      *
9047      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
9048      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
9049      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
9050      */
9051     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
9052     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9053
9054     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
9055     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9056     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9057     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9058     memset(&lr, 0, sizeof(lr));
9059     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
9060     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9061     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
9062     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9063     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9064     memset(&lr, 0, sizeof(lr));
9065     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
9066     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9067     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
9068     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9069     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9070     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9071     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9072     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9073     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9074     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9075     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9076     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9077     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9078     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9079     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9080     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9081     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9082     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9083     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9084
9085     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
9086     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9087     ptsize = 32.0;
9088     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9089     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9090
9091     hr = IDirect3DDevice9_BeginScene(device);
9092     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9093     if(SUCCEEDED(hr))
9094     {
9095         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9096         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9097         hr = IDirect3DDevice9_EndScene(device);
9098         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9099     }
9100
9101     color = getPixelColor(device, 64-4, 64-4);
9102     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
9103     color = getPixelColor(device, 64-4, 64+4);
9104     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
9105     color = getPixelColor(device, 64+4, 64+4);
9106     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
9107     color = getPixelColor(device, 64+4, 64-4);
9108     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
9109     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9110
9111     U(matrix).m[0][0] =  1.0f / 64.0f;
9112     U(matrix).m[1][1] = -1.0f / 64.0f;
9113     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
9114     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
9115
9116     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
9117     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
9118
9119     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
9120             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
9121     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
9122
9123     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
9124     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9125     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
9126     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
9127
9128     hr = IDirect3DDevice9_BeginScene(device);
9129     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9130     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9131     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9132     hr = IDirect3DDevice9_EndScene(device);
9133     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9134
9135     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
9136     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
9137     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9138     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9139     IDirect3DSurface9_Release(backbuffer);
9140     IDirect3DSurface9_Release(rt);
9141
9142     color = getPixelColor(device, 64-4, 64-4);
9143     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
9144             "Expected color 0x00ff0000, got 0x%08x.\n", color);
9145     color = getPixelColor(device, 64+4, 64-4);
9146     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
9147             "Expected color 0x00ffff00, got 0x%08x.\n", color);
9148     color = getPixelColor(device, 64-4, 64+4);
9149     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
9150             "Expected color 0x00000000, got 0x%08x.\n", color);
9151     color = getPixelColor(device, 64+4, 64+4);
9152     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9153             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9154
9155     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9156     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9157
9158     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9159     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9160     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9161     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9162     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9163     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9164     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9165     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9166     IDirect3DTexture9_Release(tex1);
9167     IDirect3DTexture9_Release(tex2);
9168
9169     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9170     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9171     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9172     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9173     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9174     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9175 }
9176
9177 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9178 {
9179     static const DWORD vshader_code[] =
9180     {
9181         0xfffe0300,                                                             /* vs_3_0                     */
9182         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0            */
9183         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0            */
9184         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                 */
9185         0x0000ffff                                                              /* end                        */
9186     };
9187     static const DWORD pshader_code1[] =
9188     {
9189         0xffff0300,                                                             /* ps_3_0                     */
9190         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9191         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
9192         0x0000ffff                                                              /* end                        */
9193     };
9194     static const DWORD pshader_code2[] =
9195     {
9196         0xffff0300,                                                             /* ps_3_0                     */
9197         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9198         0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
9199         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
9200         0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1                */
9201         0x0000ffff                                                              /* end                        */
9202     };
9203
9204     HRESULT hr;
9205     IDirect3DVertexShader9 *vs;
9206     IDirect3DPixelShader9 *ps1, *ps2;
9207     IDirect3DTexture9 *tex1, *tex2;
9208     IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
9209     D3DCAPS9 caps;
9210     DWORD color;
9211     UINT i, j;
9212     float quad[] = {
9213        -1.0,   -1.0,    0.1,
9214         1.0,   -1.0,    0.1,
9215        -1.0,    1.0,    0.1,
9216         1.0,    1.0,    0.1,
9217     };
9218     float texquad[] = {
9219        -1.0,   -1.0,    0.1,    0.0,    0.0,
9220         0.0,   -1.0,    0.1,    1.0,    0.0,
9221        -1.0,    1.0,    0.1,    0.0,    1.0,
9222         0.0,    1.0,    0.1,    1.0,    1.0,
9223
9224         0.0,   -1.0,    0.1,    0.0,    0.0,
9225         1.0,   -1.0,    0.1,    1.0,    0.0,
9226         0.0,    1.0,    0.1,    0.0,    1.0,
9227         1.0,    1.0,    0.1,    1.0,    1.0,
9228     };
9229
9230     memset(&caps, 0, sizeof(caps));
9231     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9232     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9233     if(caps.NumSimultaneousRTs < 2) {
9234         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9235         return;
9236     }
9237
9238     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9239     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9240
9241     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
9242             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
9243     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
9244
9245     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9246             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9247     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9248     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9249             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9250     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9251     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
9252     ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
9253     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
9254     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9255     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
9256     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9257
9258     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9259     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9260     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9261     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9262     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9263     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9264
9265     hr = IDirect3DDevice9_SetVertexShader(device, vs);
9266     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9267     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9268     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9269     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9270     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9271     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9272     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9273
9274     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
9275     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9276     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9277     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9278     color = getPixelColorFromSurface(readback, 8, 8);
9279     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9280             "Expected color 0x000000ff, got 0x%08x.\n", color);
9281     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9282     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9283     color = getPixelColorFromSurface(readback, 8, 8);
9284     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9285             "Expected color 0x000000ff, got 0x%08x.\n", color);
9286
9287     /* Render targets not written by the pixel shader should be unmodified. */
9288     hr = IDirect3DDevice9_SetPixelShader(device, ps1);
9289     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9290     hr = IDirect3DDevice9_BeginScene(device);
9291     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9292     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9293     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9294     hr = IDirect3DDevice9_EndScene(device);
9295     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9296     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9297     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9298     color = getPixelColorFromSurface(readback, 8, 8);
9299     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9300             "Expected color 0xff00ff00, got 0x%08x.\n", color);
9301     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9302     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9303     for (i = 6; i < 10; ++i)
9304     {
9305         for (j = 6; j < 10; ++j)
9306         {
9307             color = getPixelColorFromSurface(readback, j, i);
9308             ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9309                     "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
9310         }
9311     }
9312
9313     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9314     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9315     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9316     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9317     color = getPixelColorFromSurface(readback, 8, 8);
9318     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9319             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9320     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9321     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9322     color = getPixelColorFromSurface(readback, 8, 8);
9323     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9324             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9325
9326     hr = IDirect3DDevice9_SetPixelShader(device, ps2);
9327     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9328
9329     hr = IDirect3DDevice9_BeginScene(device);
9330     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9331     if(SUCCEEDED(hr)) {
9332         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9333         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9334
9335         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9336         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9337         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9338         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9339         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9340         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9341         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9342         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9343         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9344         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9345
9346         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9347         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9348         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9349         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9350
9351         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9352         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9353         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9354         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9355
9356         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9357         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9358
9359         hr = IDirect3DDevice9_EndScene(device);
9360         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9361     }
9362
9363     color = getPixelColor(device, 160, 240);
9364     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9365     color = getPixelColor(device, 480, 240);
9366     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9367     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9368
9369     IDirect3DPixelShader9_Release(ps2);
9370     IDirect3DPixelShader9_Release(ps1);
9371     IDirect3DVertexShader9_Release(vs);
9372     IDirect3DTexture9_Release(tex1);
9373     IDirect3DTexture9_Release(tex2);
9374     IDirect3DSurface9_Release(surf1);
9375     IDirect3DSurface9_Release(surf2);
9376     IDirect3DSurface9_Release(backbuf);
9377     IDirect3DSurface9_Release(readback);
9378 }
9379
9380 struct formats {
9381     const char *fmtName;
9382     D3DFORMAT textureFormat;
9383     DWORD resultColorBlending;
9384     DWORD resultColorNoBlending;
9385 };
9386
9387 static const struct formats test_formats[] = {
9388   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9389   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9390   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9391   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9392   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9393   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9394   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9395   { NULL, 0 }
9396 };
9397
9398 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9399 {
9400     HRESULT hr;
9401     IDirect3DTexture9 *offscreenTexture = NULL;
9402     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9403     IDirect3D9 *d3d = NULL;
9404     DWORD color;
9405     DWORD r0, g0, b0, r1, g1, b1;
9406     int fmt_index;
9407
9408     static const float quad[][5] = {
9409         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9410         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
9411         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9412         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
9413     };
9414
9415     /* Quad with R=0x10, G=0x20 */
9416     static const struct vertex quad1[] = {
9417         {-1.0f, -1.0f, 0.1f, 0x80102000},
9418         {-1.0f,  1.0f, 0.1f, 0x80102000},
9419         { 1.0f, -1.0f, 0.1f, 0x80102000},
9420         { 1.0f,  1.0f, 0.1f, 0x80102000},
9421     };
9422
9423     /* Quad with R=0x20, G=0x10 */
9424     static const struct vertex quad2[] = {
9425         {-1.0f, -1.0f, 0.1f, 0x80201000},
9426         {-1.0f,  1.0f, 0.1f, 0x80201000},
9427         { 1.0f, -1.0f, 0.1f, 0x80201000},
9428         { 1.0f,  1.0f, 0.1f, 0x80201000},
9429     };
9430
9431     IDirect3DDevice9_GetDirect3D(device, &d3d);
9432
9433     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9434     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9435     if(!backbuffer) {
9436         goto out;
9437     }
9438
9439     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9440     {
9441         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9442
9443         if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9444                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
9445         {
9446             skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
9447             continue;
9448         }
9449
9450         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9451         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9452
9453         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9454         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9455         if(!offscreenTexture) {
9456             continue;
9457         }
9458
9459         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9460         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9461         if(!offscreen) {
9462             continue;
9463         }
9464
9465         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9466         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9467
9468         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9469         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9470         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9471         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9472         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9473         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9474         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9475         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9476         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9477         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9478
9479         /* Below we will draw two quads with different colors and try to blend them together.
9480          * The result color is compared with the expected outcome.
9481          */
9482         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9483             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9484             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9485             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9486             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9487
9488             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9489             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9490
9491             /* Draw a quad using color 0x0010200 */
9492             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9493             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9494             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9495             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9496             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9497             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9498
9499             /* Draw a quad using color 0x0020100 */
9500             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9501             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9502             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9503             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9504             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9505             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9506
9507             /* We don't want to blend the result on the backbuffer */
9508             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9509             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9510
9511             /* Prepare rendering the 'blended' texture quad to the backbuffer */
9512             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9513             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9514             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9515             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9516
9517             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9518             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9519
9520             /* This time with the texture */
9521             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9522             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9523
9524             IDirect3DDevice9_EndScene(device);
9525         }
9526
9527         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9528             /* Compare the color of the center quad with our expectation */
9529             color = getPixelColor(device, 320, 240);
9530             r0 = (color & 0x00ff0000) >> 16;
9531             g0 = (color & 0x0000ff00) >>  8;
9532             b0 = (color & 0x000000ff) >>  0;
9533
9534             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9535             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9536             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9537
9538             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9539                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9540                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9541                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9542         } else {
9543             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9544              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9545              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9546             color = getPixelColor(device, 320, 240);
9547             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);
9548         }
9549         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9550
9551         IDirect3DDevice9_SetTexture(device, 0, NULL);
9552         if(offscreenTexture) {
9553             IDirect3DTexture9_Release(offscreenTexture);
9554         }
9555         if(offscreen) {
9556             IDirect3DSurface9_Release(offscreen);
9557         }
9558     }
9559
9560 out:
9561     /* restore things */
9562     if(backbuffer) {
9563         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9564         IDirect3DSurface9_Release(backbuffer);
9565     }
9566 }
9567
9568 static void tssargtemp_test(IDirect3DDevice9 *device)
9569 {
9570     HRESULT hr;
9571     DWORD color;
9572     static const struct vertex quad[] = {
9573         {-1.0,     -1.0,    0.1,    0x00ff0000},
9574         { 1.0,     -1.0,    0.1,    0x00ff0000},
9575         {-1.0,      1.0,    0.1,    0x00ff0000},
9576         { 1.0,      1.0,    0.1,    0x00ff0000}
9577     };
9578     D3DCAPS9 caps;
9579
9580     memset(&caps, 0, sizeof(caps));
9581     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9582     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9583     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9584         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9585         return;
9586     }
9587
9588     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9589     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9590
9591     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9592     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9593     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9594     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9595
9596     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9597     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9598     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9599     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9600     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9601     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9602
9603     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9604     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9605     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9606     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9607     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9608     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9609
9610     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9611     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9612
9613     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9614     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9615     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9616     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9617
9618     hr = IDirect3DDevice9_BeginScene(device);
9619     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9620     if(SUCCEEDED(hr)) {
9621         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9622         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9623         hr = IDirect3DDevice9_EndScene(device);
9624         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9625     }
9626     color = getPixelColor(device, 320, 240);
9627     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9628     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9629
9630     /* Set stage 1 back to default */
9631     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9632     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9633     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9634     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9635     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9636     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9637     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9638     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9639     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9640     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9641 }
9642
9643 struct testdata
9644 {
9645     DWORD idxVertex; /* number of instances in the first stream */
9646     DWORD idxColor; /* number of instances in the second stream */
9647     DWORD idxInstance; /* should be 1 ?? */
9648     DWORD color1; /* color 1 instance */
9649     DWORD color2; /* color 2 instance */
9650     DWORD color3; /* color 3 instance */
9651     DWORD color4; /* color 4 instance */
9652     WORD strVertex; /* specify which stream to use 0-2*/
9653     WORD strColor;
9654     WORD strInstance;
9655 };
9656
9657 static const struct testdata testcases[]=
9658 {
9659     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9660     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9661     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9662     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9663     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  4 */
9664     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9665     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9666     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9667     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  8 */
9668     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /*  9 */
9669     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9670     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9671     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9672     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9673 /*
9674     This draws one instance on some machines, no instance on others
9675     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9676 */
9677 /*
9678     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9679     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9680 */
9681 };
9682
9683 /* Drawing Indexed Geometry with instances*/
9684 static void stream_test(IDirect3DDevice9 *device)
9685 {
9686     IDirect3DVertexBuffer9 *vb = NULL;
9687     IDirect3DVertexBuffer9 *vb2 = NULL;
9688     IDirect3DVertexBuffer9 *vb3 = NULL;
9689     IDirect3DIndexBuffer9 *ib = NULL;
9690     IDirect3DVertexDeclaration9 *pDecl = NULL;
9691     IDirect3DVertexShader9 *shader = NULL;
9692     HRESULT hr;
9693     BYTE *data;
9694     DWORD color;
9695     DWORD ind;
9696     unsigned i;
9697
9698     const DWORD shader_code[] =
9699     {
9700         0xfffe0101,                                     /* vs_1_1 */
9701         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9702         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9703         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9704         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9705         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9706         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9707         0x0000ffff
9708     };
9709
9710     const float quad[][3] =
9711     {
9712         {-0.5f, -0.5f,  1.1f}, /*0 */
9713         {-0.5f,  0.5f,  1.1f}, /*1 */
9714         { 0.5f, -0.5f,  1.1f}, /*2 */
9715         { 0.5f,  0.5f,  1.1f}, /*3 */
9716     };
9717
9718     const float vertcolor[][4] =
9719     {
9720         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9721         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9722         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9723         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9724     };
9725
9726     /* 4 position for 4 instances */
9727     const float instancepos[][3] =
9728     {
9729         {-0.6f,-0.6f, 0.0f},
9730         { 0.6f,-0.6f, 0.0f},
9731         { 0.6f, 0.6f, 0.0f},
9732         {-0.6f, 0.6f, 0.0f},
9733     };
9734
9735     short indices[] = {0, 1, 2, 1, 2, 3};
9736
9737     D3DVERTEXELEMENT9 decl[] =
9738     {
9739         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9740         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9741         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9742         D3DDECL_END()
9743     };
9744
9745     /* set the default value because it isn't done in wine? */
9746     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9747     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9748
9749     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9750     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9751     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9752
9753     /* check wrong cases */
9754     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9755     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9756     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9757     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9758     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9759     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9760     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9761     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9762     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9763     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9764     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9765     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9766     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9767     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9768     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9769     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9770     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9771     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9772     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9773     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9774
9775     /* set the default value back */
9776     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9777     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9778
9779     /* create all VertexBuffers*/
9780     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9781     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9782     if(!vb) {
9783         skip("Failed to create a vertex buffer\n");
9784         return;
9785     }
9786     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9787     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9788     if(!vb2) {
9789         skip("Failed to create a vertex buffer\n");
9790         goto out;
9791     }
9792     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9793     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9794     if(!vb3) {
9795         skip("Failed to create a vertex buffer\n");
9796         goto out;
9797     }
9798
9799     /* create IndexBuffer*/
9800     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9801     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9802     if(!ib) {
9803         skip("Failed to create a index buffer\n");
9804         goto out;
9805     }
9806
9807     /* copy all Buffers (Vertex + Index)*/
9808     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9809     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9810     memcpy(data, quad, sizeof(quad));
9811     hr = IDirect3DVertexBuffer9_Unlock(vb);
9812     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9813     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9814     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9815     memcpy(data, vertcolor, sizeof(vertcolor));
9816     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9817     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9818     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9819     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9820     memcpy(data, instancepos, sizeof(instancepos));
9821     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9822     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9823     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9824     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9825     memcpy(data, indices, sizeof(indices));
9826     hr = IDirect3DIndexBuffer9_Unlock(ib);
9827     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9828
9829     /* create VertexShader */
9830     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9831     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9832     if(!shader) {
9833         skip("Failed to create a vetex shader\n");
9834         goto out;
9835     }
9836
9837     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9838     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9839
9840     hr = IDirect3DDevice9_SetIndices(device, ib);
9841     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9842
9843     /* run all tests */
9844     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9845     {
9846         struct testdata act = testcases[i];
9847         decl[0].Stream = act.strVertex;
9848         decl[1].Stream = act.strColor;
9849         decl[2].Stream = act.strInstance;
9850         /* create VertexDeclarations */
9851         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9852         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9853
9854         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9855         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9856
9857         hr = IDirect3DDevice9_BeginScene(device);
9858         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9859         if(SUCCEEDED(hr))
9860         {
9861             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9862             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9863
9864             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9865             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9866             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9867             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9868
9869             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9870             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9871             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9872             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9873
9874             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9875             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9876             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9877             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9878
9879             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9880             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9881             hr = IDirect3DDevice9_EndScene(device);
9882             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9883
9884             /* set all StreamSource && StreamSourceFreq back to default */
9885             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9886             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9887             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9888             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9889             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9890             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9891             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9892             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9893             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9894             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9895             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9896             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9897         }
9898
9899         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9900         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9901
9902         color = getPixelColor(device, 160, 360);
9903         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9904         color = getPixelColor(device, 480, 360);
9905         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9906         color = getPixelColor(device, 480, 120);
9907         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9908         color = getPixelColor(device, 160, 120);
9909         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9910
9911         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9912         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9913     }
9914
9915     hr = IDirect3DDevice9_SetIndices(device, NULL);
9916     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9917
9918 out:
9919     if(vb) IDirect3DVertexBuffer9_Release(vb);
9920     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9921     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9922     if(ib)IDirect3DIndexBuffer9_Release(ib);
9923     if(shader)IDirect3DVertexShader9_Release(shader);
9924 }
9925
9926 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9927     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9928     IDirect3DTexture9 *dsttex = NULL;
9929     HRESULT hr;
9930     DWORD color;
9931     D3DRECT r1 = {0,  0,  50,  50 };
9932     D3DRECT r2 = {50, 0,  100, 50 };
9933     D3DRECT r3 = {50, 50, 100, 100};
9934     D3DRECT r4 = {0,  50,  50, 100};
9935     const float quad[] = {
9936         -1.0,   -1.0,   0.1,    0.0,    0.0,
9937          1.0,   -1.0,   0.1,    1.0,    0.0,
9938         -1.0,    1.0,   0.1,    0.0,    1.0,
9939          1.0,    1.0,   0.1,    1.0,    1.0,
9940     };
9941
9942     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9943     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9944
9945     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9946     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9947     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9948     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9949
9950     if(!src || !dsttex) {
9951         skip("One or more test resources could not be created\n");
9952         goto cleanup;
9953     }
9954
9955     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9956     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9957
9958     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9959     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9960
9961     /* Clear the StretchRect destination for debugging */
9962     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9963     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9964     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9965     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9966
9967     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9968     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9969
9970     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9971     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9972     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9973     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9974     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9975     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9976     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9977     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9978
9979     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9980      * the target -> texture GL blit path
9981      */
9982     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9983     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9984     IDirect3DSurface9_Release(dst);
9985
9986     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9987     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9988
9989     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9990     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9991     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9992     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9993     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9994     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9995     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9996     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9997
9998     hr = IDirect3DDevice9_BeginScene(device);
9999     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
10000     if(SUCCEEDED(hr)) {
10001         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10002         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
10003         hr = IDirect3DDevice9_EndScene(device);
10004         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
10005     }
10006
10007     color = getPixelColor(device, 160, 360);
10008     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
10009     color = getPixelColor(device, 480, 360);
10010     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
10011     color = getPixelColor(device, 480, 120);
10012     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
10013     color = getPixelColor(device, 160, 120);
10014     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
10015     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10016     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10017
10018     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10019     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
10020     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10021     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
10022
10023 cleanup:
10024     if(src) IDirect3DSurface9_Release(src);
10025     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
10026     if(dsttex) IDirect3DTexture9_Release(dsttex);
10027 }
10028
10029 static void texop_test(IDirect3DDevice9 *device)
10030 {
10031     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
10032     IDirect3DTexture9 *texture = NULL;
10033     D3DLOCKED_RECT locked_rect;
10034     D3DCOLOR color;
10035     D3DCAPS9 caps;
10036     HRESULT hr;
10037     unsigned i;
10038
10039     static const struct {
10040         float x, y, z;
10041         float s, t;
10042         D3DCOLOR diffuse;
10043     } quad[] = {
10044         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10045         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10046         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10047         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
10048     };
10049
10050     static const D3DVERTEXELEMENT9 decl_elements[] = {
10051         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10052         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
10053         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
10054         D3DDECL_END()
10055     };
10056
10057     static const struct {
10058         D3DTEXTUREOP op;
10059         const char *name;
10060         DWORD caps_flag;
10061         D3DCOLOR result;
10062     } test_data[] = {
10063         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10064         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
10065         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
10066         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
10067         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10068         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10069         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
10070         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10071         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10072         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10073         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10074         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
10075         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
10076         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10077         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10078         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
10079         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
10080         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10081         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
10082         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
10083         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
10084         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
10085         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
10086     };
10087
10088     memset(&caps, 0, sizeof(caps));
10089     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10090     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10091
10092     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
10093     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
10094     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
10095     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
10096
10097     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10098     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10099     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10100     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10101     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
10102     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10103     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10104     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10105     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10106
10107     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
10108     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10109     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10110     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10111     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10112     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10113
10114     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10115     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10116
10117     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10118     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10119     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
10120     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10121     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
10122     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10123
10124     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10125     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10126
10127     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
10128     {
10129         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
10130         {
10131             skip("tex operation %s not supported\n", test_data[i].name);
10132             continue;
10133         }
10134
10135         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
10136         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
10137
10138         hr = IDirect3DDevice9_BeginScene(device);
10139         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10140
10141         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10142         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10143
10144         hr = IDirect3DDevice9_EndScene(device);
10145         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10146
10147         color = getPixelColor(device, 320, 240);
10148         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
10149                 test_data[i].name, color, test_data[i].result);
10150
10151         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10152         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10153     }
10154
10155     if (texture) IDirect3DTexture9_Release(texture);
10156     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
10157 }
10158
10159 static void yuv_color_test(IDirect3DDevice9 *device) {
10160     HRESULT hr;
10161     IDirect3DSurface9 *surface = NULL, *target = NULL;
10162     unsigned int fmt, i;
10163     D3DFORMAT format;
10164     const char *fmt_string;
10165     D3DLOCKED_RECT lr;
10166     IDirect3D9 *d3d;
10167     HRESULT color;
10168     DWORD ref_color_left, ref_color_right;
10169
10170     struct {
10171         DWORD in;           /* The input color */
10172         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
10173         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
10174         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
10175         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
10176     } test_data[] = {
10177     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
10178      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
10179      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
10180      * that
10181      */
10182       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
10183       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
10184       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
10185       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
10186       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
10187       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
10188       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
10189       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
10190       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
10191       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
10192       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
10193       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
10194       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
10195       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
10196
10197       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
10198       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
10199       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
10200       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
10201     };
10202
10203     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
10204     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
10205     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
10206     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
10207
10208     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
10209     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10210
10211     for(fmt = 0; fmt < 2; fmt++) {
10212         if(fmt == 0) {
10213             format = D3DFMT_UYVY;
10214             fmt_string = "D3DFMT_UYVY";
10215         } else {
10216             format = D3DFMT_YUY2;
10217             fmt_string = "D3DFMT_YUY2";
10218         }
10219
10220         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
10221                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
10222                        */
10223         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
10224                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
10225             skip("%s is not supported\n", fmt_string);
10226             continue;
10227         }
10228
10229         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
10230         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
10231         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
10232
10233         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
10234             if(fmt == 0) {
10235                 ref_color_left = test_data[i].uyvy_left;
10236                 ref_color_right = test_data[i].uyvy_right;
10237             } else {
10238                 ref_color_left = test_data[i].yuy2_left;
10239                 ref_color_right = test_data[i].yuy2_right;
10240             }
10241
10242             memset(&lr, 0, sizeof(lr));
10243             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
10244             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
10245             *((DWORD *) lr.pBits) = test_data[i].in;
10246             hr = IDirect3DSurface9_UnlockRect(surface);
10247             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10248
10249             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10250             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10251             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10252             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10253
10254             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10255              * prevent running into precision problems, read a far left and far right pixel. In the future we may
10256              * want to add tests for the filtered pixels as well.
10257              *
10258              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10259              * differently, so we need a max diff of 16
10260              */
10261             color = getPixelColor(device, 40, 240);
10262
10263             /* Newer versions of the Nvidia Windows driver mix up the U and V channels, breaking all the tests
10264              * where U != V. Skip the entire test if this bug in this case
10265              */
10266             if (broken(test_data[i].in == 0xff000000 && color == 0x00008800 && format == D3DFMT_UYVY))
10267             {
10268                 skip("Nvidia channel confusion bug detected, skipping YUV tests\n");
10269                 IDirect3DSurface9_Release(surface);
10270                 goto out;
10271             }
10272
10273             ok(color_match(color, ref_color_left, 18),
10274                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10275                test_data[i].in, color, ref_color_left, fmt_string);
10276             color = getPixelColor(device, 600, 240);
10277             ok(color_match(color, ref_color_right, 18),
10278                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10279                test_data[i].in, color, ref_color_right, fmt_string);
10280             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10281             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10282         }
10283         IDirect3DSurface9_Release(surface);
10284     }
10285
10286 out:
10287     IDirect3DSurface9_Release(target);
10288     IDirect3D9_Release(d3d);
10289 }
10290
10291 static void texop_range_test(IDirect3DDevice9 *device)
10292 {
10293     static const struct {
10294         float x, y, z;
10295         D3DCOLOR diffuse;
10296     } quad[] = {
10297         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10298         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10299         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10300         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10301     };
10302     HRESULT hr;
10303     IDirect3DTexture9 *texture;
10304     D3DLOCKED_RECT locked_rect;
10305     D3DCAPS9 caps;
10306     DWORD color;
10307
10308     /* We need ADD and SUBTRACT operations */
10309     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10310     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10311     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10312         skip("D3DTOP_ADD is not supported, skipping value range test\n");
10313         return;
10314     }
10315     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10316         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10317         return;
10318     }
10319
10320     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10321     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10322     /* Stage 1: result = diffuse(=1.0) + diffuse
10323      * stage 2: result = result - tfactor(= 0.5)
10324      */
10325     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10326     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10327     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10328     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10329     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10330     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10331     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10332     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10333     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10334     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10335     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10336     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10337     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10338     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10339
10340     hr = IDirect3DDevice9_BeginScene(device);
10341     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10342     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10343     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10344     hr = IDirect3DDevice9_EndScene(device);
10345     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10346
10347     color = getPixelColor(device, 320, 240);
10348     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10349        color);
10350     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10351     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10352
10353     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10354     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10355     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10356     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10357     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10358     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10359     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10360     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10361     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10362
10363     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10364      * stage 2: result = result + diffuse(1.0)
10365      */
10366     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10367     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10368     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10369     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10370     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10371     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10372     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10373     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10374     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10375     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10376     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10377     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10378     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10379     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10380
10381     hr = IDirect3DDevice9_BeginScene(device);
10382     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10383     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10384     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10385     hr = IDirect3DDevice9_EndScene(device);
10386     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10387
10388     color = getPixelColor(device, 320, 240);
10389     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10390        color);
10391     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10392     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10393
10394     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10395     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10396     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10397     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10398     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10399     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10400     IDirect3DTexture9_Release(texture);
10401 }
10402
10403 static void alphareplicate_test(IDirect3DDevice9 *device) {
10404     struct vertex quad[] = {
10405         { -1.0,    -1.0,    0.1,    0x80ff00ff },
10406         {  1.0,    -1.0,    0.1,    0x80ff00ff },
10407         { -1.0,     1.0,    0.1,    0x80ff00ff },
10408         {  1.0,     1.0,    0.1,    0x80ff00ff },
10409     };
10410     HRESULT hr;
10411     DWORD color;
10412
10413     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10414     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10415
10416     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10417     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10418
10419     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10420     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10421     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10422     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10423
10424     hr = IDirect3DDevice9_BeginScene(device);
10425     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10426     if(SUCCEEDED(hr)) {
10427         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10428         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10429         hr = IDirect3DDevice9_EndScene(device);
10430         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10431     }
10432
10433     color = getPixelColor(device, 320, 240);
10434     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10435        color);
10436     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10437     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10438
10439     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10440     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10441
10442 }
10443
10444 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10445     HRESULT hr;
10446     D3DCAPS9 caps;
10447     DWORD color;
10448     struct vertex quad[] = {
10449         { -1.0,    -1.0,    0.1,    0x408080c0 },
10450         {  1.0,    -1.0,    0.1,    0x408080c0 },
10451         { -1.0,     1.0,    0.1,    0x408080c0 },
10452         {  1.0,     1.0,    0.1,    0x408080c0 },
10453     };
10454
10455     memset(&caps, 0, sizeof(caps));
10456     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10457     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10458     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10459         skip("D3DTOP_DOTPRODUCT3 not supported\n");
10460         return;
10461     }
10462
10463     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10464     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10465
10466     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10467     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10468
10469     /* dp3_x4 r0, diffuse_bias, tfactor_bias
10470      * mov r0.a, diffuse.a
10471      * mov r0, r0.a
10472      *
10473      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10474      * 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
10475      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10476      */
10477     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10478     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10479     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10480     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10481     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10482     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10483     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10484     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10485     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10486     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10487     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10488     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10489     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10490     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10491     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10492     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10493     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10494     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10495
10496     hr = IDirect3DDevice9_BeginScene(device);
10497     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10498     if(SUCCEEDED(hr)) {
10499         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10500         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10501         hr = IDirect3DDevice9_EndScene(device);
10502         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10503     }
10504
10505     color = getPixelColor(device, 320, 240);
10506     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10507        color);
10508     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10509     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10510
10511     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10512     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10513     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10514     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10515     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10516     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10517 }
10518
10519 static void zwriteenable_test(IDirect3DDevice9 *device) {
10520     HRESULT hr;
10521     DWORD color;
10522     struct vertex quad1[] = {
10523         { -1.0,  -1.0,  0.1,    0x00ff0000},
10524         { -1.0,   1.0,  0.1,    0x00ff0000},
10525         {  1.0,  -1.0,  0.1,    0x00ff0000},
10526         {  1.0,   1.0,  0.1,    0x00ff0000},
10527     };
10528     struct vertex quad2[] = {
10529         { -1.0,  -1.0,  0.9,    0x0000ff00},
10530         { -1.0,   1.0,  0.9,    0x0000ff00},
10531         {  1.0,  -1.0,  0.9,    0x0000ff00},
10532         {  1.0,   1.0,  0.9,    0x0000ff00},
10533     };
10534
10535     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10536     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10537
10538     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10539     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10540     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10541     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10542     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10543     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10544     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10545     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10546
10547     hr = IDirect3DDevice9_BeginScene(device);
10548     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10549     if(SUCCEEDED(hr)) {
10550         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10551          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10552          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10553          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10554          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10555          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10556          */
10557         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10558         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10559         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10560         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10561         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10562         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10563
10564         hr = IDirect3DDevice9_EndScene(device);
10565         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10566     }
10567
10568     color = getPixelColor(device, 320, 240);
10569     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10570        color);
10571     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10572     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10573
10574     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10575     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10576 }
10577
10578 static void alphatest_test(IDirect3DDevice9 *device) {
10579 #define ALPHATEST_PASSED 0x0000ff00
10580 #define ALPHATEST_FAILED 0x00ff0000
10581     struct {
10582         D3DCMPFUNC  func;
10583         DWORD       color_less;
10584         DWORD       color_equal;
10585         DWORD       color_greater;
10586     } testdata[] = {
10587         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10588         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10589         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10590         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10591         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10592         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10593         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10594         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10595     };
10596     unsigned int i, j;
10597     HRESULT hr;
10598     DWORD color;
10599     struct vertex quad[] = {
10600         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10601         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10602         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10603         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10604     };
10605     D3DCAPS9 caps;
10606
10607     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10608     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10609     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10610     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10611
10612     for(j = 0; j < 2; j++) {
10613         if(j == 1) {
10614             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10615              * the alpha test either for performance reasons(floating point RTs) or to work
10616              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10617              * codepath for ffp and shader in this case, and the test should cover both
10618              */
10619             IDirect3DPixelShader9 *ps;
10620             DWORD shader_code[] = {
10621                 0xffff0101,                                 /* ps_1_1           */
10622                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10623                 0x0000ffff                                  /* end              */
10624             };
10625             memset(&caps, 0, sizeof(caps));
10626             hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10627             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10628             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10629                 break;
10630             }
10631
10632             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10633             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10634             hr = IDirect3DDevice9_SetPixelShader(device, ps);
10635             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10636             IDirect3DPixelShader9_Release(ps);
10637         }
10638
10639         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10640             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10641             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10642
10643             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10644             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10645             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10646             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10647             hr = IDirect3DDevice9_BeginScene(device);
10648             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10649             if(SUCCEEDED(hr)) {
10650                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10651                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10652                 hr = IDirect3DDevice9_EndScene(device);
10653                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10654             }
10655             color = getPixelColor(device, 320, 240);
10656             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10657             color, testdata[i].color_less, testdata[i].func);
10658             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10659             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10660
10661             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10662             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10663             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10664             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10665             hr = IDirect3DDevice9_BeginScene(device);
10666             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10667             if(SUCCEEDED(hr)) {
10668                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10669                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10670                 hr = IDirect3DDevice9_EndScene(device);
10671                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10672             }
10673             color = getPixelColor(device, 320, 240);
10674             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10675             color, testdata[i].color_equal, testdata[i].func);
10676             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10677             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10678
10679             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10680             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10681             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10682             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10683             hr = IDirect3DDevice9_BeginScene(device);
10684             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10685             if(SUCCEEDED(hr)) {
10686                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10687                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10688                 hr = IDirect3DDevice9_EndScene(device);
10689                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10690             }
10691             color = getPixelColor(device, 320, 240);
10692             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10693             color, testdata[i].color_greater, testdata[i].func);
10694             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10695             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10696         }
10697     }
10698
10699     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10700     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10701     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10702     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10703 }
10704
10705 static void sincos_test(IDirect3DDevice9 *device) {
10706     const DWORD sin_shader_code[] = {
10707         0xfffe0200,                                                                 /* vs_2_0                       */
10708         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10709         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10710         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10711         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10712         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10713         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10714         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10715         0x0000ffff                                                                  /* end                          */
10716     };
10717     const DWORD cos_shader_code[] = {
10718         0xfffe0200,                                                                 /* vs_2_0                       */
10719         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10720         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10721         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10722         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10723         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10724         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10725         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10726         0x0000ffff                                                                  /* end                          */
10727     };
10728     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10729     HRESULT hr;
10730     struct {
10731         float x, y, z;
10732     } data[1280];
10733     unsigned int i;
10734     float sincosc1[4] = {D3DSINCOSCONST1};
10735     float sincosc2[4] = {D3DSINCOSCONST2};
10736
10737     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10738     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10739
10740     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10741     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10742     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10743     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10744     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10745     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10746     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10747     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10748     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10749     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10750
10751     /* Generate a point from -1 to 1 every 0.5 pixels */
10752     for(i = 0; i < 1280; i++) {
10753         data[i].x = (-640.0 + i) / 640.0;
10754         data[i].y = 0.0;
10755         data[i].z = 0.1;
10756     }
10757
10758     hr = IDirect3DDevice9_BeginScene(device);
10759     if(SUCCEEDED(hr)) {
10760         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10761         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10762         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10763         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10764
10765         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10766         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10767         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10768         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10769
10770         hr = IDirect3DDevice9_EndScene(device);
10771         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10772     }
10773     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10774     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10775     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10776
10777     IDirect3DDevice9_SetVertexShader(device, NULL);
10778     IDirect3DVertexShader9_Release(sin_shader);
10779     IDirect3DVertexShader9_Release(cos_shader);
10780 }
10781
10782 static void loop_index_test(IDirect3DDevice9 *device) {
10783     const DWORD shader_code[] = {
10784         0xfffe0200,                                                 /* vs_2_0                   */
10785         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10786         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10787         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10788         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10789         0x0000001d,                                                 /* endloop                  */
10790         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10791         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10792         0x0000ffff                                                  /* END                      */
10793     };
10794     IDirect3DVertexShader9 *shader;
10795     HRESULT hr;
10796     DWORD color;
10797     const float quad[] = {
10798         -1.0,   -1.0,   0.1,
10799          1.0,   -1.0,   0.1,
10800         -1.0,    1.0,   0.1,
10801          1.0,    1.0,   0.1
10802     };
10803     const float zero[4] = {0, 0, 0, 0};
10804     const float one[4] = {1, 1, 1, 1};
10805     int i0[4] = {2, 10, -3, 0};
10806     float values[4];
10807
10808     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10809     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10810     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10811     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10812     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10813     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10814     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10815     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10816
10817     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10818     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10819     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10820     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10821     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10822     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10823     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10824     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10825     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10826     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10827     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10828     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10829     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10830     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10831     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10832     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10833     values[0] = 1.0;
10834     values[1] = 1.0;
10835     values[2] = 0.0;
10836     values[3] = 0.0;
10837     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10838     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10839     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10840     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10841     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10842     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10843     values[0] = -1.0;
10844     values[1] = 0.0;
10845     values[2] = 0.0;
10846     values[3] = 0.0;
10847     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10848     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10849     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10850     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10851     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10852     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10853     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10854     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10855     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10856     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10857
10858     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10859     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10860
10861     hr = IDirect3DDevice9_BeginScene(device);
10862     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10863     if(SUCCEEDED(hr))
10864     {
10865         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10866         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10867         hr = IDirect3DDevice9_EndScene(device);
10868         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10869     }
10870     color = getPixelColor(device, 320, 240);
10871     ok(color_match(color, 0x0000ff00, 1),
10872        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10873     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10874     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10875
10876     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10877     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10878     IDirect3DVertexShader9_Release(shader);
10879 }
10880
10881 static void sgn_test(IDirect3DDevice9 *device) {
10882     const DWORD shader_code[] = {
10883         0xfffe0200,                                                             /* vs_2_0                       */
10884         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10885         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10886         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10887         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10888         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10889         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10890         0x0000ffff                                                              /* end                          */
10891     };
10892     IDirect3DVertexShader9 *shader;
10893     HRESULT hr;
10894     DWORD color;
10895     const float quad[] = {
10896         -1.0,   -1.0,   0.1,
10897          1.0,   -1.0,   0.1,
10898         -1.0,    1.0,   0.1,
10899          1.0,    1.0,   0.1
10900     };
10901
10902     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10903     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10904     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10905     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10906     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10907     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10908     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10909     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10910
10911     hr = IDirect3DDevice9_BeginScene(device);
10912     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10913     if(SUCCEEDED(hr))
10914     {
10915         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10916         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10917         hr = IDirect3DDevice9_EndScene(device);
10918         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10919     }
10920     color = getPixelColor(device, 320, 240);
10921     ok(color_match(color, 0x008000ff, 1),
10922        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10923     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10924     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10925
10926     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10927     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10928     IDirect3DVertexShader9_Release(shader);
10929 }
10930
10931 static void viewport_test(IDirect3DDevice9 *device) {
10932     HRESULT hr;
10933     DWORD color;
10934     D3DVIEWPORT9 vp, old_vp;
10935     BOOL draw_failed = TRUE;
10936     const float quad[] =
10937     {
10938         -0.5,   -0.5,   0.1,
10939          0.5,   -0.5,   0.1,
10940         -0.5,    0.5,   0.1,
10941          0.5,    0.5,   0.1
10942     };
10943
10944     memset(&old_vp, 0, sizeof(old_vp));
10945     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10946     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10947
10948     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10949     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10950
10951     /* Test a viewport with Width and Height bigger than the surface dimensions
10952      *
10953      * TODO: Test Width < surface.width, but X + Width > surface.width
10954      * TODO: Test Width < surface.width, what happens with the height?
10955      *
10956      * The expected behavior is that the viewport behaves like the "default"
10957      * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
10958      * MinZ = 0.0, MaxZ = 1.0.
10959      *
10960      * Starting with Windows 7 the behavior among driver versions is not
10961      * consistent. The SetViewport call is accepted on all drivers. Some
10962      * drivers(older nvidia ones) refuse to draw and return an error. Newer
10963      * nvidia drivers draw, but use the actual values in the viewport and only
10964      * display the upper left part on the surface.
10965      */
10966     memset(&vp, 0, sizeof(vp));
10967     vp.X = 0;
10968     vp.Y = 0;
10969     vp.Width = 10000;
10970     vp.Height = 10000;
10971     vp.MinZ = 0.0;
10972     vp.MaxZ = 0.0;
10973     hr = IDirect3DDevice9_SetViewport(device, &vp);
10974     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10975
10976     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10977     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10978     hr = IDirect3DDevice9_BeginScene(device);
10979     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10980     if(SUCCEEDED(hr))
10981     {
10982         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10983         ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10984         draw_failed = FAILED(hr);
10985         hr = IDirect3DDevice9_EndScene(device);
10986         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10987     }
10988
10989     if(!draw_failed)
10990     {
10991         color = getPixelColor(device, 158, 118);
10992         ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10993         color = getPixelColor(device, 162, 118);
10994         ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10995         color = getPixelColor(device, 158, 122);
10996         ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10997         color = getPixelColor(device, 162, 122);
10998         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
10999
11000         color = getPixelColor(device, 478, 358);
11001         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
11002         color = getPixelColor(device, 482, 358);
11003         ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
11004         color = getPixelColor(device, 478, 362);
11005         ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
11006         color = getPixelColor(device, 482, 362);
11007         ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
11008     }
11009
11010     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11011     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
11012
11013     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
11014     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
11015 }
11016
11017 /* This test tests depth clamping / clipping behaviour:
11018  *   - With software vertex processing, depth values are clamped to the
11019  *     minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
11020  *     when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
11021  *     same as regular vertices here.
11022  *   - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
11023  *     Normal vertices are always clipped. Pretransformed vertices are
11024  *     clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
11025  *   - The viewport's MinZ/MaxZ is irrelevant for this.
11026  */
11027 static void depth_clamp_test(IDirect3DDevice9 *device)
11028 {
11029     const struct tvertex quad1[] =
11030     {
11031         {  0.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
11032         {640.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
11033         {  0.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
11034         {640.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
11035     };
11036     const struct tvertex quad2[] =
11037     {
11038         {  0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
11039         {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
11040         {  0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
11041         {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
11042     };
11043     const struct tvertex quad3[] =
11044     {
11045         {112.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
11046         {208.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
11047         {112.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
11048         {208.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
11049     };
11050     const struct tvertex quad4[] =
11051     {
11052         { 42.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
11053         {112.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
11054         { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
11055         {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
11056     };
11057     const struct vertex quad5[] =
11058     {
11059         { -0.5f,   0.5f, 10.0f,       0xff14f914},
11060         {  0.5f,   0.5f, 10.0f,       0xff14f914},
11061         { -0.5f,  -0.5f, 10.0f,       0xff14f914},
11062         {  0.5f,  -0.5f, 10.0f,       0xff14f914},
11063     };
11064     const struct vertex quad6[] =
11065     {
11066         { -1.0f,   0.5f, 10.0f,      0xfff91414},
11067         {  1.0f,   0.5f, 10.0f,      0xfff91414},
11068         { -1.0f,  0.25f, 10.0f,      0xfff91414},
11069         {  1.0f,  0.25f, 10.0f,      0xfff91414},
11070     };
11071
11072     D3DVIEWPORT9 vp;
11073     D3DCOLOR color;
11074     D3DCAPS9 caps;
11075     HRESULT hr;
11076
11077     vp.X = 0;
11078     vp.Y = 0;
11079     vp.Width = 640;
11080     vp.Height = 480;
11081     vp.MinZ = 0.0;
11082     vp.MaxZ = 7.5;
11083
11084     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11085     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11086
11087     hr = IDirect3DDevice9_SetViewport(device, &vp);
11088     if(FAILED(hr))
11089     {
11090         /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
11091          * the tests because the 7.5 is just intended to show that it doesn't have
11092          * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
11093          * viewport and continue.
11094          */
11095         ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
11096         vp.MaxZ = 1.0;
11097         hr = IDirect3DDevice9_SetViewport(device, &vp);
11098     }
11099     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11100
11101     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
11102     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11103
11104     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
11105     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11106     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11107     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11108     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11109     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11110     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11111     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11112
11113     hr = IDirect3DDevice9_BeginScene(device);
11114     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11115
11116     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11117     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11118
11119     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11120     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11121     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11122     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11123
11124     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11125     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11126
11127     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11128     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11129     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
11130     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11131
11132     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
11133     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11134
11135     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11136     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11137
11138     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
11139     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11140
11141     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11142     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11143
11144     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
11145     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11146
11147     hr = IDirect3DDevice9_EndScene(device);
11148     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11149
11150     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
11151     {
11152         color = getPixelColor(device, 75, 75);
11153         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11154         color = getPixelColor(device, 150, 150);
11155         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11156         color = getPixelColor(device, 320, 240);
11157         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11158         color = getPixelColor(device, 320, 330);
11159         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11160         color = getPixelColor(device, 320, 330);
11161         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11162     }
11163     else
11164     {
11165         color = getPixelColor(device, 75, 75);
11166         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11167         color = getPixelColor(device, 150, 150);
11168         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11169         color = getPixelColor(device, 320, 240);
11170         ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11171         color = getPixelColor(device, 320, 330);
11172         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11173         color = getPixelColor(device, 320, 330);
11174         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11175     }
11176
11177     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11178     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11179
11180     vp.MinZ = 0.0;
11181     vp.MaxZ = 1.0;
11182     hr = IDirect3DDevice9_SetViewport(device, &vp);
11183     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11184 }
11185
11186 static void depth_bounds_test(IDirect3DDevice9 *device)
11187 {
11188     const struct tvertex quad1[] =
11189     {
11190         {    0,    0, 0.0f, 1, 0xfff9e814},
11191         {  640,    0, 0.0f, 1, 0xfff9e814},
11192         {    0,  480, 1.0f, 1, 0xfff9e814},
11193         {  640,  480, 1.0f, 1, 0xfff9e814},
11194     };
11195     const struct tvertex quad2[] =
11196     {
11197         {    0,    0,  0.6f, 1, 0xff002b7f},
11198         {  640,    0,  0.6f, 1, 0xff002b7f},
11199         {    0,  480,  0.6f, 1, 0xff002b7f},
11200         {  640,  480,  0.6f, 1, 0xff002b7f},
11201     };
11202     const struct tvertex quad3[] =
11203     {
11204         {    0,  100, 0.6f, 1, 0xfff91414},
11205         {  640,  100, 0.6f, 1, 0xfff91414},
11206         {    0,  160, 0.6f, 1, 0xfff91414},
11207         {  640,  160, 0.6f, 1, 0xfff91414},
11208     };
11209
11210     union {
11211         DWORD d;
11212         float f;
11213     } tmpvalue;
11214
11215     IDirect3D9 *d3d = NULL;
11216     IDirect3DSurface9 *offscreen_surface = NULL;
11217     D3DCOLOR color;
11218     HRESULT hr;
11219
11220     IDirect3DDevice9_GetDirect3D(device, &d3d);
11221     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11222             0,  D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
11223         skip("No NVDB (depth bounds test) support\n");
11224         IDirect3D9_Release(d3d);
11225         return;
11226     }
11227     IDirect3D9_Release(d3d);
11228
11229     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
11230             MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
11231     ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
11232     if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
11233
11234     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
11235     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11236
11237     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11238     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11239     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
11240     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11241     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11242     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11243     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11244     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11245
11246
11247     hr = IDirect3DDevice9_BeginScene(device);
11248     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11249
11250     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11251     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11252
11253     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11254     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11255
11256     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
11257     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11258
11259     tmpvalue.f = 0.625;
11260     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11261     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11262
11263     tmpvalue.f = 0.75;
11264     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
11265     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11266
11267     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11268     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11269
11270     tmpvalue.f = 0.75;
11271     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11272     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11273
11274     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11275     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11276
11277     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
11278     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11279
11280     hr = IDirect3DDevice9_EndScene(device);
11281     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11282
11283     color = getPixelColor(device, 150, 130);
11284     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11285     color = getPixelColor(device, 150, 200);
11286     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11287     color = getPixelColor(device, 150, 300-5);
11288     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11289     color = getPixelColor(device, 150, 300+5);
11290     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11291     color = getPixelColor(device, 150, 330);
11292     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11293     color = getPixelColor(device, 150, 360-5);
11294     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11295     color = getPixelColor(device, 150, 360+5);
11296     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11297
11298     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11299     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11300 }
11301
11302 static void depth_buffer_test(IDirect3DDevice9 *device)
11303 {
11304     static const struct vertex quad1[] =
11305     {
11306         { -1.0,  1.0, 0.33f, 0xff00ff00},
11307         {  1.0,  1.0, 0.33f, 0xff00ff00},
11308         { -1.0, -1.0, 0.33f, 0xff00ff00},
11309         {  1.0, -1.0, 0.33f, 0xff00ff00},
11310     };
11311     static const struct vertex quad2[] =
11312     {
11313         { -1.0,  1.0, 0.50f, 0xffff00ff},
11314         {  1.0,  1.0, 0.50f, 0xffff00ff},
11315         { -1.0, -1.0, 0.50f, 0xffff00ff},
11316         {  1.0, -1.0, 0.50f, 0xffff00ff},
11317     };
11318     static const struct vertex quad3[] =
11319     {
11320         { -1.0,  1.0, 0.66f, 0xffff0000},
11321         {  1.0,  1.0, 0.66f, 0xffff0000},
11322         { -1.0, -1.0, 0.66f, 0xffff0000},
11323         {  1.0, -1.0, 0.66f, 0xffff0000},
11324     };
11325     static const DWORD expected_colors[4][4] =
11326     {
11327         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11328         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11329         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11330         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11331     };
11332
11333     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
11334     unsigned int i, j;
11335     D3DVIEWPORT9 vp;
11336     D3DCOLOR color;
11337     HRESULT hr;
11338
11339     vp.X = 0;
11340     vp.Y = 0;
11341     vp.Width = 640;
11342     vp.Height = 480;
11343     vp.MinZ = 0.0;
11344     vp.MaxZ = 1.0;
11345
11346     hr = IDirect3DDevice9_SetViewport(device, &vp);
11347     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11348
11349     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11350     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11351     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11352     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11353     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11354     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11355     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11356     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11357     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11358     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11359
11360     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11361     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11362     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
11363             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11364     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11365     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11366             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11367     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11368     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11369             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
11370     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11371
11372     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11373     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11374     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11375     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11376
11377     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11378     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11379     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11380     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11381
11382     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11383     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11384     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11385     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11386
11387     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11388     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11389     hr = IDirect3DDevice9_BeginScene(device);
11390     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11391     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11392     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11393     hr = IDirect3DDevice9_EndScene(device);
11394     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11395
11396     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11397     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11398
11399     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11400     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11401
11402     hr = IDirect3DDevice9_BeginScene(device);
11403     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11404     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11405     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11406     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11407     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11408     hr = IDirect3DDevice9_EndScene(device);
11409     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11410
11411     for (i = 0; i < 4; ++i)
11412     {
11413         for (j = 0; j < 4; ++j)
11414         {
11415             unsigned int x = 80 * ((2 * j) + 1);
11416             unsigned int y = 60 * ((2 * i) + 1);
11417             color = getPixelColor(device, x, y);
11418             ok(color_match(color, expected_colors[i][j], 0),
11419                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11420         }
11421     }
11422
11423     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11424     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11425
11426     IDirect3DSurface9_Release(backbuffer);
11427     IDirect3DSurface9_Release(rt3);
11428     IDirect3DSurface9_Release(rt2);
11429     IDirect3DSurface9_Release(rt1);
11430 }
11431
11432 /* Test that partial depth copies work the way they're supposed to. The clear
11433  * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
11434  * the following draw should only copy back the part that was modified. */
11435 static void depth_buffer2_test(IDirect3DDevice9 *device)
11436 {
11437     static const struct vertex quad[] =
11438     {
11439         { -1.0,  1.0, 0.66f, 0xffff0000},
11440         {  1.0,  1.0, 0.66f, 0xffff0000},
11441         { -1.0, -1.0, 0.66f, 0xffff0000},
11442         {  1.0, -1.0, 0.66f, 0xffff0000},
11443     };
11444
11445     IDirect3DSurface9 *backbuffer, *rt1, *rt2;
11446     unsigned int i, j;
11447     D3DVIEWPORT9 vp;
11448     D3DCOLOR color;
11449     HRESULT hr;
11450
11451     vp.X = 0;
11452     vp.Y = 0;
11453     vp.Width = 640;
11454     vp.Height = 480;
11455     vp.MinZ = 0.0;
11456     vp.MaxZ = 1.0;
11457
11458     hr = IDirect3DDevice9_SetViewport(device, &vp);
11459     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11460
11461     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11462     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11463     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11464     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11465     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11466     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11467     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11468     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11469     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11470     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11471
11472     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11473             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11474     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11475     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11476             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11477     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11478     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11479     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11480
11481     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11482     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11483     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11484     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11485
11486     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11487     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11488     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
11489     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11490
11491     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11492     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11493     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11494     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11495
11496     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11497     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11498
11499     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11500     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11501
11502     hr = IDirect3DDevice9_BeginScene(device);
11503     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11504     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11505     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11506     hr = IDirect3DDevice9_EndScene(device);
11507     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11508
11509     for (i = 0; i < 4; ++i)
11510     {
11511         for (j = 0; j < 4; ++j)
11512         {
11513             unsigned int x = 80 * ((2 * j) + 1);
11514             unsigned int y = 60 * ((2 * i) + 1);
11515             color = getPixelColor(device, x, y);
11516             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11517                     "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
11518         }
11519     }
11520
11521     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11522     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11523
11524     IDirect3DSurface9_Release(backbuffer);
11525     IDirect3DSurface9_Release(rt2);
11526     IDirect3DSurface9_Release(rt1);
11527 }
11528
11529 static void depth_blit_test(IDirect3DDevice9 *device)
11530 {
11531     static const struct vertex quad1[] =
11532     {
11533         { -1.0,  1.0, 0.50f, 0xff00ff00},
11534         {  1.0,  1.0, 0.50f, 0xff00ff00},
11535         { -1.0, -1.0, 0.50f, 0xff00ff00},
11536         {  1.0, -1.0, 0.50f, 0xff00ff00},
11537     };
11538     static const struct vertex quad2[] =
11539     {
11540         { -1.0,  1.0, 0.66f, 0xff0000ff},
11541         {  1.0,  1.0, 0.66f, 0xff0000ff},
11542         { -1.0, -1.0, 0.66f, 0xff0000ff},
11543         {  1.0, -1.0, 0.66f, 0xff0000ff},
11544     };
11545     static const DWORD expected_colors[4][4] =
11546     {
11547         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11548         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11549         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11550         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11551     };
11552
11553     IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
11554     RECT src_rect, dst_rect;
11555     unsigned int i, j;
11556     D3DVIEWPORT9 vp;
11557     D3DCOLOR color;
11558     HRESULT hr;
11559
11560     vp.X = 0;
11561     vp.Y = 0;
11562     vp.Width = 640;
11563     vp.Height = 480;
11564     vp.MinZ = 0.0;
11565     vp.MaxZ = 1.0;
11566
11567     hr = IDirect3DDevice9_SetViewport(device, &vp);
11568     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11569
11570     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11571     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11572     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11573     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11574     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11575     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11576     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11577     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11578     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
11579     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11580
11581     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11582     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11583     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11584     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11585     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11586     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11587     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11588     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11589
11590     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11591     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11592     SetRect(&dst_rect, 0, 0, 480, 360);
11593     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11594     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11595     SetRect(&dst_rect, 0, 0, 320, 240);
11596     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11597     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11598
11599     /* Partial blit. */
11600     SetRect(&src_rect, 0, 0, 320, 240);
11601     SetRect(&dst_rect, 0, 0, 320, 240);
11602     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11603     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11604     /* Flipped. */
11605     SetRect(&src_rect, 0, 0, 640, 480);
11606     SetRect(&dst_rect, 0, 480, 640, 0);
11607     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11608     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11609     /* Full, explicit. */
11610     SetRect(&src_rect, 0, 0, 640, 480);
11611     SetRect(&dst_rect, 0, 0, 640, 480);
11612     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11613     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11614     /* Filtered blit. */
11615     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11616     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11617     /* Depth -> color blit.*/
11618     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11619     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11620     IDirect3DSurface9_Release(backbuffer);
11621     /* Full surface, different sizes */
11622     hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
11623     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11624     hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
11625     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11626
11627     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11628     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11629     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11630     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11631     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11632     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11633
11634     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11635     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11636     hr = IDirect3DDevice9_BeginScene(device);
11637     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11638     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11639     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11640     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11641     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11642     hr = IDirect3DDevice9_EndScene(device);
11643     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11644
11645     for (i = 0; i < 4; ++i)
11646     {
11647         for (j = 0; j < 4; ++j)
11648         {
11649             unsigned int x = 80 * ((2 * j) + 1);
11650             unsigned int y = 60 * ((2 * i) + 1);
11651             color = getPixelColor(device, x, y);
11652             ok(color_match(color, expected_colors[i][j], 0),
11653                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11654         }
11655     }
11656
11657     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11658     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11659
11660     IDirect3DSurface9_Release(ds3);
11661     IDirect3DSurface9_Release(ds2);
11662     IDirect3DSurface9_Release(ds1);
11663 }
11664
11665 static void intz_test(IDirect3DDevice9 *device)
11666 {
11667     static const DWORD ps_code[] =
11668     {
11669         0xffff0200,                                                             /* ps_2_0                       */
11670         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11671         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11672         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11673         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11674         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11675         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11676         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11677         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11678         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
11679         0x0000ffff,                                                             /* end                          */
11680     };
11681     struct
11682     {
11683         float x, y, z;
11684         float s, t, p, q;
11685     }
11686     quad[] =
11687     {
11688         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11689         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11690         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11691         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11692     },
11693     half_quad_1[] =
11694     {
11695         { -1.0f,  0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11696         {  1.0f,  0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11697         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11698         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11699     },
11700     half_quad_2[] =
11701     {
11702         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11703         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11704         { -1.0f,  0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11705         {  1.0f,  0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11706     };
11707     struct
11708     {
11709         UINT x, y;
11710         D3DCOLOR color;
11711     }
11712     expected_colors[] =
11713     {
11714         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11715         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11716         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11717         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11718         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11719         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11720         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11721         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11722     };
11723
11724     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11725     IDirect3DTexture9 *texture;
11726     IDirect3DPixelShader9 *ps;
11727     IDirect3DSurface9 *ds;
11728     IDirect3D9 *d3d9;
11729     D3DCAPS9 caps;
11730     HRESULT hr;
11731     UINT i;
11732
11733     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11734     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11735     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11736     {
11737         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11738         return;
11739     }
11740     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
11741     {
11742         skip("No unconditional NP2 texture support, skipping INTZ test.\n");
11743         return;
11744     }
11745
11746     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11747     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11748
11749     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11750             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11751     if (FAILED(hr))
11752     {
11753         skip("No INTZ support, skipping INTZ test.\n");
11754         return;
11755     }
11756
11757     IDirect3D9_Release(d3d9);
11758
11759     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11760     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11761     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11762     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11763
11764     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11765             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11766     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11767     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11768             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11769     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11770     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11771     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11772
11773     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11774     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11775     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11776     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11777     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11778     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11779     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11780     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11781     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11782     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11783
11784     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11785     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11786     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11787     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11788     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11789     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11790     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11791     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11792     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11793     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11794
11795     /* Render offscreen, using the INTZ texture as depth buffer */
11796     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11797     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11798     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11799     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11800     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11801     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11802     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11803     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11804
11805     /* Setup the depth/stencil surface. */
11806     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11807     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11808
11809     hr = IDirect3DDevice9_BeginScene(device);
11810     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11811     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11812     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11813     hr = IDirect3DDevice9_EndScene(device);
11814     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11815
11816     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11817     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11818     IDirect3DSurface9_Release(ds);
11819     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11820     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11821     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11822     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11823     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11824     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11825
11826     /* Read the depth values back. */
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     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11835     {
11836         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11837         ok(color_match(color, expected_colors[i].color, 1),
11838                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11839                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11840     }
11841
11842     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11843     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11844
11845     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11846     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11847     IDirect3DTexture9_Release(texture);
11848
11849     /* Render onscreen while using the INTZ texture as depth buffer */
11850     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11851             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11852     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11853     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11854     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11855     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11856     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11857     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11858
11859     /* Setup the depth/stencil surface. */
11860     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11861     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11862
11863     hr = IDirect3DDevice9_BeginScene(device);
11864     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11865     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11866     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11867     hr = IDirect3DDevice9_EndScene(device);
11868     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11869
11870     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11871     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11872     IDirect3DSurface9_Release(ds);
11873     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11874     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11875     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11876     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11877
11878     /* Read the depth values back. */
11879     hr = IDirect3DDevice9_BeginScene(device);
11880     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11881     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11882     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11883     hr = IDirect3DDevice9_EndScene(device);
11884     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11885
11886     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11887     {
11888         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11889         ok(color_match(color, expected_colors[i].color, 1),
11890                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11891                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11892     }
11893
11894     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11895     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11896
11897     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11898     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11899     IDirect3DTexture9_Release(texture);
11900
11901     /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
11902     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
11903             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11904     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11905     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11906
11907     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11908     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11909     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11910     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11911     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11912     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11913
11914     /* Setup the depth/stencil surface. */
11915     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11916     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11917
11918     hr = IDirect3DDevice9_BeginScene(device);
11919     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11920     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
11921     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11922     hr = IDirect3DDevice9_EndScene(device);
11923     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11924
11925     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11926     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11927
11928     hr = IDirect3DDevice9_BeginScene(device);
11929     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11930     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
11931     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11932     hr = IDirect3DDevice9_EndScene(device);
11933     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11934
11935     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11936     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11937     IDirect3DSurface9_Release(ds);
11938     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11939     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11940     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11941     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11942
11943     /* Read the depth values back. */
11944     hr = IDirect3DDevice9_BeginScene(device);
11945     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11946     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11947     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11948     hr = IDirect3DDevice9_EndScene(device);
11949     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11950
11951     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11952     {
11953         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11954         ok(color_match(color, expected_colors[i].color, 1),
11955                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11956                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11957     }
11958
11959     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11960     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11961
11962     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11963     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11964     IDirect3DSurface9_Release(original_ds);
11965     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11966     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11967     IDirect3DTexture9_Release(texture);
11968     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11969     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11970     IDirect3DPixelShader9_Release(ps);
11971
11972     IDirect3DSurface9_Release(original_rt);
11973     IDirect3DSurface9_Release(rt);
11974 }
11975
11976 static void shadow_test(IDirect3DDevice9 *device)
11977 {
11978     static const DWORD ps_code[] =
11979     {
11980         0xffff0200,                                                             /* ps_2_0                       */
11981         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11982         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11983         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11984         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11985         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11986         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11987         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11988         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11989         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11990         0x0000ffff,                                                             /* end                          */
11991     };
11992     struct
11993     {
11994         D3DFORMAT format;
11995         const char *name;
11996     }
11997     formats[] =
11998     {
11999         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
12000         {D3DFMT_D32,            "D3DFMT_D32"},
12001         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
12002         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
12003         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
12004         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
12005         {D3DFMT_D16,            "D3DFMT_D16"},
12006         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
12007         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
12008     };
12009     struct
12010     {
12011         float x, y, z;
12012         float s, t, p, q;
12013     }
12014     quad[] =
12015     {
12016         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
12017         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
12018         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
12019         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
12020     };
12021     struct
12022     {
12023         UINT x, y;
12024         D3DCOLOR color;
12025     }
12026     expected_colors[] =
12027     {
12028         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12029         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12030         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12031         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12032         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12033         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12034         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12035         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
12036     };
12037
12038     IDirect3DSurface9 *original_ds, *original_rt, *rt;
12039     IDirect3DPixelShader9 *ps;
12040     IDirect3D9 *d3d9;
12041     D3DCAPS9 caps;
12042     HRESULT hr;
12043     UINT i;
12044
12045     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12046     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12047     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
12048     {
12049         skip("No pixel shader 2.0 support, skipping shadow test.\n");
12050         return;
12051     }
12052
12053     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
12054     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12055     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12056     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12057     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
12058     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
12059
12060     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
12061             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12062     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12063     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12064     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12065
12066     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
12067     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12068     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12069     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12070     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
12071     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12072     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12073     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12074     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12075     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12076
12077     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
12078     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12079     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
12080     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12081     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
12082     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12083     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
12084     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12085     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12086     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12087
12088     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
12089     {
12090         D3DFORMAT format = formats[i].format;
12091         IDirect3DTexture9 *texture;
12092         IDirect3DSurface9 *ds;
12093         unsigned int j;
12094
12095         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12096                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
12097         if (FAILED(hr)) continue;
12098
12099         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
12100                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
12101         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12102
12103         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
12104         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12105
12106         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12107         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12108
12109         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12110         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12111
12112         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12113         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12114
12115         /* Setup the depth/stencil surface. */
12116         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
12117         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12118
12119         hr = IDirect3DDevice9_BeginScene(device);
12120         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12121         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12122         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12123         hr = IDirect3DDevice9_EndScene(device);
12124         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12125
12126         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
12127         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12128         IDirect3DSurface9_Release(ds);
12129
12130         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12131         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12132
12133         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12134         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12135
12136         hr = IDirect3DDevice9_SetPixelShader(device, ps);
12137         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12138
12139         /* Do the actual shadow mapping. */
12140         hr = IDirect3DDevice9_BeginScene(device);
12141         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12142         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12143         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12144         hr = IDirect3DDevice9_EndScene(device);
12145         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12146
12147         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12148         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12149         IDirect3DTexture9_Release(texture);
12150
12151         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
12152         {
12153             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
12154             ok(color_match(color, expected_colors[j].color, 0),
12155                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
12156                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
12157                     formats[i].name, color);
12158         }
12159
12160         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12161         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12162     }
12163
12164     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12165     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12166     IDirect3DPixelShader9_Release(ps);
12167
12168     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
12169     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12170     IDirect3DSurface9_Release(original_ds);
12171
12172     IDirect3DSurface9_Release(original_rt);
12173     IDirect3DSurface9_Release(rt);
12174
12175     IDirect3D9_Release(d3d9);
12176 }
12177
12178 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
12179 {
12180     const struct vertex quad1[] =
12181     {
12182         {-1.0f, -1.0f, 0.0f, 0xfff9e814},
12183         { 1.0f, -1.0f, 0.0f, 0xfff9e814},
12184         {-1.0f,  1.0f, 0.0f, 0xfff9e814},
12185         { 1.0f,  1.0f, 0.0f, 0xfff9e814},
12186     };
12187     const struct vertex quad2[] =
12188     {
12189         {-1.0f, -1.0f, 0.0f, 0xff002b7f},
12190         { 1.0f, -1.0f, 0.0f, 0xff002b7f},
12191         {-1.0f,  1.0f, 0.0f, 0xff002b7f},
12192         { 1.0f,  1.0f, 0.0f, 0xff002b7f},
12193     };
12194     D3DCOLOR color;
12195     HRESULT hr;
12196
12197     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
12198     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12199
12200     hr = IDirect3DDevice9_BeginScene(device);
12201     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12202
12203     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12204     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12205
12206     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12207     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12208     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12209     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12210
12211     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
12212     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12213     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12214     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12215
12216     hr = IDirect3DDevice9_EndScene(device);
12217     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12218
12219     color = getPixelColor(device, 1, 240);
12220     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12221     color = getPixelColor(device, 638, 240);
12222     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
12223
12224     color = getPixelColor(device, 1, 241);
12225     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12226     color = getPixelColor(device, 638, 241);
12227     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
12228 }
12229
12230 static void clip_planes_test(IDirect3DDevice9 *device)
12231 {
12232     const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
12233
12234     const DWORD shader_code[] = {
12235         0xfffe0200, /* vs_2_0 */
12236         0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12237         0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
12238         0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12239         0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
12240         0x0000ffff /* end */
12241     };
12242     IDirect3DVertexShader9 *shader;
12243
12244     IDirect3DTexture9 *offscreen = NULL;
12245     IDirect3DSurface9 *offscreen_surface, *original_rt;
12246     HRESULT hr;
12247
12248     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12249     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12250
12251     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12252     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12253     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12254     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12255     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12256     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12257     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
12258     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12259
12260     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12261     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12262     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12263     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
12264
12265     IDirect3DDevice9_SetClipPlane(device, 0, plane0);
12266
12267     clip_planes(device, "Onscreen FFP");
12268
12269     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
12270     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12271     hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
12272     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12273     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12274     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12275
12276     clip_planes(device, "Offscreen FFP");
12277
12278     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12279     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12280
12281     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12282     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
12283     hr = IDirect3DDevice9_SetVertexShader(device, shader);
12284     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
12285
12286     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12287     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12288
12289     clip_planes(device, "Onscreen vertex shader");
12290
12291     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12292     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12293
12294     clip_planes(device, "Offscreen vertex shader");
12295
12296     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12297     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12298
12299     IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12300     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12301     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12302     IDirect3DVertexShader9_Release(shader);
12303     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12304     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12305     IDirect3DSurface9_Release(original_rt);
12306     IDirect3DSurface9_Release(offscreen_surface);
12307     IDirect3DTexture9_Release(offscreen);
12308 }
12309
12310 static void fp_special_test(IDirect3DDevice9 *device)
12311 {
12312     static const DWORD vs_header[] =
12313     {
12314         0xfffe0200,                                                             /* vs_2_0                       */
12315         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
12316         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
12317         0x0200001f, 0x80000005, 0x900f0001,                                     /* dcl_texcoord0 v1             */
12318     };
12319
12320     static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001};         /* log r0.x, v1.x               */
12321     static const DWORD vs_pow[] =
12322             {0x03000020, 0x80010000, 0x90000001, 0x90000001};                   /* pow r0.x, v1.x, v1.x         */
12323     static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001};         /* nrm r0.xyz, v1.x             */
12324     static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001};        /* rcp r0.x, v1.x               */
12325     static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001};        /* rcp r0.x, -v1.x              */
12326     static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001};        /* rsq r0.x, v1.x               */
12327     static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001};        /* rsq r0.x, -v1.x              */
12328     static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001,          /* lit r0, v1.xxxx              */
12329             0x02000001, 0x80010000, 0x80aa0000};                                /* mov r0.x, v0.z               */
12330
12331     static const DWORD vs_footer[] =
12332     {
12333         0x03000005, 0x80020000, 0x80000000, 0xa0ff0000,                         /* mul r0.y, r0.x, c0.w         */
12334         0x0300000d, 0x80040000, 0x80000000, 0x80550000,                         /* sge r0.z, r0.x, r0.y         */
12335         0x0300000d, 0x80020000, 0x80e40000, 0x80000000,                         /* sge r0.y, r0, r0.x           */
12336         0x03000005, 0x80040000, 0x80550000, 0x80e40000,                         /* mul r0.z, r0.y, r0           */
12337         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
12338         0x0300000c, 0x80020000, 0x80000000, 0x80000000,                         /* slt r0.y, r0.x, r0.x         */
12339         0x03000002, 0x80040000, 0x80550000, 0x80550000,                         /* add r0.z, r0.y, r0.y         */
12340         0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000,                         /* slt r0.y, c0.x, r0.w         */
12341         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
12342         0x03000002, 0x80040000, 0x81550000, 0xa0e40000,                         /* add r0.z, -r0.y, c0          */
12343         0x0300000c, 0x80080000, 0xa0000000, 0x80e40000,                         /* slt r0.w, c0.x, r0           */
12344         0x03000005, 0x80040000, 0x80ff0000, 0x80e40000,                         /* mul r0.z, r0.w, r0           */
12345         0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000,             /* mad r0.y, r0.z, c0, r0       */
12346         0x02000001, 0xe0030000, 0x80e40000,                                     /* mov oT0.xy, r0               */
12347         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
12348         0x0000ffff,                                                             /* end                          */
12349     };
12350
12351     static const struct
12352     {
12353         const char *name;
12354         const DWORD *ops;
12355         DWORD size;
12356         D3DCOLOR r600;
12357         D3DCOLOR nv40;
12358         D3DCOLOR nv50;
12359     }
12360     vs_body[] =
12361     {
12362         /* The basic ideas here are:
12363          *     2.0 * +/-INF == +/-INF
12364          *     NAN != NAN
12365          *
12366          * The vertex shader value is written to the red component, with 0.0
12367          * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
12368          * result in 0x00. The pixel shader value is written to the green
12369          * component, but here 0.0 also results in 0x00. The actual value is
12370          * written to the blue component.
12371          *
12372          * There are considerable differences between graphics cards in how
12373          * these are handled, but pow and nrm never generate INF or NAN. */
12374         {"log",     vs_log,     sizeof(vs_log),     0x00000000, 0x00ff0000, 0x00ff7f00},
12375         {"pow",     vs_pow,     sizeof(vs_pow),     0x000000ff, 0x0000ff00, 0x000000ff},
12376         {"nrm",     vs_nrm,     sizeof(vs_nrm),     0x00ff0000, 0x0000ff00, 0x00ff0000},
12377         {"rcp1",    vs_rcp1,    sizeof(vs_rcp1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12378         {"rcp2",    vs_rcp2,    sizeof(vs_rcp2),    0x00000000, 0x00ff0000, 0x00ff7f00},
12379         {"rsq1",    vs_rsq1,    sizeof(vs_rsq1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12380         {"rsq2",    vs_rsq2,    sizeof(vs_rsq2),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12381         {"lit",     vs_lit,     sizeof(vs_lit),     0x00ff0000, 0x00ff0000, 0x00ff0000},
12382     };
12383
12384     static const DWORD ps_code[] =
12385     {
12386         0xffff0200,                                                             /* ps_2_0                       */
12387         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
12388         0x0200001f, 0x80000000, 0xb0030000,                                     /* dcl t0.xy                    */
12389         0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000,                         /* max r1.x, t0, c0             */
12390         0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000,                         /* min r0.x, t0, c0             */
12391         0x03000002, 0x80010000, 0x80e40000, 0x81e40001,                         /* add r0.x, r0, -r1            */
12392         0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000,             /* mad r1.x, t0, c0.w. -t0      */
12393         0x02000023, 0x80010002, 0x80e40001,                                     /* abs r2.x, r1                 */
12394         0x02000023, 0x80010000, 0x80e40000,                                     /* abs r0.x, r0                 */
12395         0x02000023, 0x80010001, 0xb0e40000,                                     /* abs r1.x, t0                 */
12396         0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r2, c0.z, c0      */
12397         0x02000023, 0x80010002, 0x80e40002,                                     /* abs r2.x, r2                 */
12398         0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r1.x, -r1, c0.z, c0      */
12399         0x02000023, 0x80010001, 0x80e40001,                                     /* abs r1.x, r1                 */
12400         0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r3.x, -r2, c0.z, c0      */
12401         0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r1, c0.z, c0      */
12402         0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000,             /* cmp r0.x, -r0, c0.y, c0      */
12403         0x03000005, 0x80010002, 0x80e40002, 0x80e40003,                         /* mul r2.x, r2, r3             */
12404         0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000,             /* cmp r0.x, -r2, c0.z, r0      */
12405         0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000,             /* cmp r0.y, -r1.x, r0.x, c0.x  */
12406         0x02000001, 0x80050000, 0xb0c90000,                                     /* mov r0.xz, t0.yzxw           */
12407         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.w, c0.z               */
12408         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
12409         0x0000ffff,                                                             /* end                          */
12410     };
12411
12412     struct
12413     {
12414         float x, y, z;
12415         float s;
12416     }
12417     quad[] =
12418     {
12419         { -1.0f,  1.0f, 0.0f, 0.0f},
12420         {  1.0f,  1.0f, 1.0f, 0.0f},
12421         { -1.0f, -1.0f, 0.0f, 0.0f},
12422         {  1.0f, -1.0f, 1.0f, 0.0f},
12423     };
12424
12425     IDirect3DPixelShader9 *ps;
12426     UINT body_size = 0;
12427     DWORD *vs_code;
12428     D3DCAPS9 caps;
12429     HRESULT hr;
12430     UINT i;
12431
12432     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12433     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12434     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12435     {
12436         skip("No shader model 2.0 support, skipping floating point specials test.\n");
12437         return;
12438     }
12439
12440     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
12441     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12442
12443     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12444     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12445     hr = IDirect3DDevice9_SetPixelShader(device, ps);
12446     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12447
12448     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12449     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12450
12451     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
12452     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12453
12454     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12455     {
12456         if (vs_body[i].size > body_size) body_size = vs_body[i].size;
12457     }
12458
12459     vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
12460     memcpy(vs_code, vs_header, sizeof(vs_header));
12461
12462     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12463     {
12464         DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
12465         IDirect3DVertexShader9 *vs;
12466         D3DCOLOR color;
12467
12468         memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
12469         offset += vs_body[i].size / sizeof(*vs_body[i].ops);
12470         memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
12471
12472         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
12473         ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
12474         hr = IDirect3DDevice9_SetVertexShader(device, vs);
12475         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12476
12477         hr = IDirect3DDevice9_BeginScene(device);
12478         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12479         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12480         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12481         hr = IDirect3DDevice9_EndScene(device);
12482         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12483
12484         color = getPixelColor(device, 320, 240);
12485         ok(color_match(color, vs_body[i].r600, 1)
12486                 || color_match(color, vs_body[i].nv40, 1)
12487                 || color_match(color, vs_body[i].nv50, 1),
12488                 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
12489                 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
12490
12491         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12492         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12493
12494         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12495         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12496         IDirect3DVertexShader9_Release(vs);
12497     }
12498
12499     HeapFree(GetProcessHeap(), 0, vs_code);
12500
12501     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12502     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12503     IDirect3DPixelShader9_Release(ps);
12504 }
12505
12506 static void srgbwrite_format_test(IDirect3DDevice9 *device)
12507 {
12508     IDirect3D9 *d3d;
12509     IDirect3DSurface9 *rt, *backbuffer;
12510     IDirect3DTexture9 *texture;
12511     HRESULT hr;
12512     int i;
12513     DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
12514     static const struct
12515     {
12516         D3DFORMAT fmt;
12517         const char *name;
12518     }
12519     formats[] =
12520     {
12521         { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
12522         { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
12523         { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
12524         { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
12525         { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
12526     };
12527     static const struct
12528     {
12529         float x, y, z;
12530         float u, v;
12531     }
12532     quad[] =
12533     {
12534         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12535         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12536         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12537         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12538     };
12539
12540     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12541     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12542     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12543     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12544     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
12545     ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
12546     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12547     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12548     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12549     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12550
12551     for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
12552     {
12553         if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12554                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
12555         {
12556             skip("Format %s not supported as render target, skipping test.\n",
12557                     formats[i].name);
12558             continue;
12559         }
12560
12561         hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
12562                                             D3DPOOL_DEFAULT, &texture, NULL);
12563         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12564         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
12565         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12566
12567         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
12568         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12569         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12570         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12571         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
12572         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12573
12574         hr = IDirect3DDevice9_BeginScene(device);
12575         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12576         if(SUCCEEDED(hr))
12577         {
12578             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
12579             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12580             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
12581             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12582             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12583             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12584
12585             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
12586             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12587             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12588             ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12589             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
12590             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12591             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12592             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12593             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12594             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12595             hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12596             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12597
12598             hr = IDirect3DDevice9_EndScene(device);
12599             ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12600         }
12601
12602         IDirect3DSurface9_Release(rt);
12603         IDirect3DTexture9_Release(texture);
12604
12605         color = getPixelColor(device, 360, 240);
12606         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12607                                     D3DUSAGE_QUERY_SRGBWRITE,
12608                                     D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
12609         {
12610             /* Big slop for R5G6B5 */
12611             ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
12612                 formats[i].name, color_srgb, color);
12613         }
12614         else
12615         {
12616             /* Big slop for R5G6B5 */
12617             ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
12618                 formats[i].name, color_rgb, color);
12619         }
12620
12621         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12622         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12623     }
12624
12625     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12626     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12627
12628     IDirect3D9_Release(d3d);
12629     IDirect3DSurface9_Release(backbuffer);
12630 }
12631
12632 static void ds_size_test(IDirect3DDevice9 *device)
12633 {
12634     IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
12635     HRESULT hr;
12636     DWORD num_passes;
12637     struct
12638     {
12639         float x, y, z;
12640     }
12641     quad[] =
12642     {
12643         {-1.0,  -1.0,   0.0 },
12644         {-1.0,   1.0,   0.0 },
12645         { 1.0,  -1.0,   0.0 },
12646         { 1.0,   1.0,   0.0 }
12647     };
12648
12649     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12650     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12651     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
12652     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
12653     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
12654     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
12655
12656     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12657     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12658     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
12659     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12660     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12661     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12662     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12663     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12664     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12665     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12666     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
12667     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
12668     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12669     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12670     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12671     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12672     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12673     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12674
12675     /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
12676      * but does not change the surface's contents. */
12677     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
12678     ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
12679     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
12680     ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
12681     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
12682     ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12683
12684     /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
12685
12686     /* Turning on any depth-related state results in a ValidateDevice failure */
12687     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12688     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12689     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12690     ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12691         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12692     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12693     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12694     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12695     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12696     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12697     ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12698         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12699
12700     /* Try to draw with the device in an invalid state */
12701     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12702     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12703     hr = IDirect3DDevice9_BeginScene(device);
12704     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12705     if(SUCCEEDED(hr))
12706     {
12707         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12708         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12709         hr = IDirect3DDevice9_EndScene(device);
12710         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12711
12712         /* Don't check the resulting draw unless we find an app that needs it. On nvidia ValidateDevice
12713          * returns CONFLICTINGRENDERSTATE, so the result is undefined. On AMD d3d seems to assume the
12714          * stored Z buffer value is 0.0 for all pixels, even those that are covered by the depth buffer */
12715     }
12716
12717     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12718     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12719     hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12720     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12721     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12722     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12723
12724     IDirect3DSurface9_Release(readback);
12725     IDirect3DSurface9_Release(ds);
12726     IDirect3DSurface9_Release(rt);
12727     IDirect3DSurface9_Release(old_rt);
12728     IDirect3DSurface9_Release(old_ds);
12729 }
12730
12731 static void unbound_sampler_test(IDirect3DDevice9 *device)
12732 {
12733     HRESULT hr;
12734     IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
12735     IDirect3DSurface9 *rt, *old_rt;
12736     DWORD color;
12737
12738     static const DWORD ps_code[] =
12739     {
12740         0xffff0200,                                     /* ps_2_0           */
12741         0x0200001f, 0x90000000, 0xa00f0800,             /* dcl_2d s0        */
12742         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12743         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12744         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12745         0x0000ffff,                                     /* end              */
12746     };
12747     static const DWORD ps_code_cube[] =
12748     {
12749         0xffff0200,                                     /* ps_2_0           */
12750         0x0200001f, 0x98000000, 0xa00f0800,             /* dcl_cube s0      */
12751         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12752         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12753         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12754         0x0000ffff,                                     /* end              */
12755     };
12756     static const DWORD ps_code_volume[] =
12757     {
12758         0xffff0200,                                     /* ps_2_0           */
12759         0x0200001f, 0xa0000000, 0xa00f0800,             /* dcl_volume s0    */
12760         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12761         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12762         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12763         0x0000ffff,                                     /* end              */
12764     };
12765
12766     static const struct
12767     {
12768         float x, y, z;
12769         float u, v;
12770     }
12771     quad[] =
12772     {
12773         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12774         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12775         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12776         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12777     };
12778
12779     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12780     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
12781
12782     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12783     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12784     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
12785     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12786     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
12787     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12788
12789     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
12790     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12791
12792     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12793     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12794
12795     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12796     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12797
12798     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
12799     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12800
12801     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
12802     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
12803
12804     hr = IDirect3DDevice9_SetPixelShader(device, ps);
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     /* Now try with a cube texture */
12822     hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
12823     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12824
12825     hr = IDirect3DDevice9_BeginScene(device);
12826     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12827     if (SUCCEEDED(hr))
12828     {
12829         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12830         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12831
12832         hr = IDirect3DDevice9_EndScene(device);
12833         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12834     }
12835
12836     color = getPixelColorFromSurface(rt, 32, 32);
12837     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12838
12839     /* And then with a volume texture */
12840     hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
12841     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12842
12843     hr = IDirect3DDevice9_BeginScene(device);
12844     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12845     if (SUCCEEDED(hr))
12846     {
12847         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12848         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12849
12850         hr = IDirect3DDevice9_EndScene(device);
12851         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12852     }
12853
12854     color = getPixelColorFromSurface(rt, 32, 32);
12855     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12856
12857     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12858     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12859
12860     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12861     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12862
12863     IDirect3DSurface9_Release(rt);
12864     IDirect3DSurface9_Release(old_rt);
12865     IDirect3DPixelShader9_Release(ps);
12866     IDirect3DPixelShader9_Release(ps_cube);
12867     IDirect3DPixelShader9_Release(ps_volume);
12868 }
12869
12870 static void update_surface_test(IDirect3DDevice9 *device)
12871 {
12872     static const BYTE blocks[][8] =
12873     {
12874         {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
12875         {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
12876         {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
12877         {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
12878         {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
12879         {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
12880         {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
12881     };
12882     static const struct
12883     {
12884         UINT x, y;
12885         D3DCOLOR color;
12886     }
12887     expected_colors[] =
12888     {
12889         { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
12890         { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
12891         {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
12892         {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12893         {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12894         {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12895         {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
12896     };
12897     static const struct
12898     {
12899         float x, y, z, w;
12900         float u, v;
12901     }
12902     tri[] =
12903     {
12904         {  0.0f, 480.0f, 0.0f,  1.0f,   0.0f, 0.0f},
12905         {  0.0f,   0.0f, 0.0f,  1.0f,   0.0f, 1.0f},
12906         {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
12907     };
12908     static const RECT rect_2x2 = {0, 0, 2, 2};
12909     static const struct
12910     {
12911         UINT src_level;
12912         UINT dst_level;
12913         const RECT *r;
12914         HRESULT hr;
12915     }
12916     block_size_tests[] =
12917     {
12918         {1, 0, NULL,      D3D_OK},
12919         {0, 1, NULL,      D3DERR_INVALIDCALL},
12920         {5, 4, NULL,      D3DERR_INVALIDCALL},
12921         {4, 5, NULL,      D3DERR_INVALIDCALL},
12922         {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
12923         {5, 5, &rect_2x2, D3D_OK},
12924     };
12925
12926     IDirect3DSurface9 *src_surface, *dst_surface;
12927     IDirect3DTexture9 *src_tex, *dst_tex;
12928     IDirect3D9 *d3d;
12929     UINT count, i;
12930     HRESULT hr;
12931
12932     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12933     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12934
12935     hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12936             D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
12937     IDirect3D9_Release(d3d);
12938     if (FAILED(hr))
12939     {
12940         skip("DXT1 not supported, skipping test.\n");
12941         return;
12942     }
12943
12944     IDirect3D9_Release(d3d);
12945
12946     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
12947     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12948     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
12949     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12950
12951     count = IDirect3DTexture9_GetLevelCount(src_tex);
12952     ok(count == 7, "Got level count %u, expected 7.\n", count);
12953
12954     for (i = 0; i < count; ++i)
12955     {
12956         UINT row_count, block_count, x, y;
12957         D3DSURFACE_DESC desc;
12958         BYTE *row, *block;
12959         D3DLOCKED_RECT r;
12960
12961         hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
12962         ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
12963
12964         hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
12965         ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
12966
12967         row_count = ((desc.Height + 3) & ~3) / 4;
12968         block_count = ((desc.Width + 3) & ~3) / 4;
12969         row = r.pBits;
12970
12971         for (y = 0; y < row_count; ++y)
12972         {
12973             block = row;
12974             for (x = 0; x < block_count; ++x)
12975             {
12976                 memcpy(block, blocks[i], sizeof(blocks[i]));
12977                 block += sizeof(blocks[i]);
12978             }
12979             row += r.Pitch;
12980         }
12981
12982         hr = IDirect3DTexture9_UnlockRect(src_tex, i);
12983         ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
12984     }
12985
12986     for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
12987     {
12988         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
12989         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12990         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
12991         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12992
12993         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
12994         ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
12995                 hr, i, block_size_tests[i].hr);
12996
12997         IDirect3DSurface9_Release(dst_surface);
12998         IDirect3DSurface9_Release(src_surface);
12999     }
13000
13001     for (i = 0; i < count; ++i)
13002     {
13003         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
13004         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
13005         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
13006         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
13007
13008         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
13009         ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
13010
13011         IDirect3DSurface9_Release(dst_surface);
13012         IDirect3DSurface9_Release(src_surface);
13013     }
13014
13015     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13016     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13017     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13018     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13019     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
13020     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13021     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
13022     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13023     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
13024     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
13025     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
13026     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
13027
13028     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
13029     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13030
13031     hr = IDirect3DDevice9_BeginScene(device);
13032     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13033     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
13034     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13035     hr = IDirect3DDevice9_EndScene(device);
13036     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13037
13038     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13039     {
13040         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13041         ok(color_match(color, expected_colors[i].color, 0),
13042                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13043                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13044     }
13045
13046     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13047     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13048
13049     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13050     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13051     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
13052     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
13053     IDirect3DTexture9_Release(dst_tex);
13054     IDirect3DTexture9_Release(src_tex);
13055 }
13056
13057 static void multisample_get_rtdata_test(IDirect3DDevice9 *device)
13058 {
13059     IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
13060     IDirect3D9 *d3d9;
13061     HRESULT hr;
13062
13063     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
13064     ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
13065     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13066             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13067     IDirect3D9_Release(d3d9);
13068     if (FAILED(hr))
13069     {
13070         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
13071         return;
13072     }
13073
13074     hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
13075             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13076     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13077     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
13078             D3DPOOL_SYSTEMMEM, &readback, NULL);
13079     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13080
13081     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13082     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13083     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13084     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13085
13086     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13087     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13088     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13089     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13090
13091     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
13092     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13093     hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
13094     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
13095
13096     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13097     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13098     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13099     ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13100
13101     IDirect3DSurface9_Release(original_ds);
13102     IDirect3DSurface9_Release(original_rt);
13103     IDirect3DSurface9_Release(readback);
13104     IDirect3DSurface9_Release(rt);
13105 }
13106
13107 static void multisampled_depth_buffer_test(IDirect3D9 *d3d9)
13108 {
13109     IDirect3DDevice9 *device = 0;
13110     IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
13111     D3DCAPS9 caps;
13112     HRESULT hr;
13113     D3DPRESENT_PARAMETERS present_parameters;
13114     unsigned int i;
13115     static const struct
13116     {
13117         float x, y, z;
13118         D3DCOLOR color;
13119     }
13120     quad_1[] =
13121     {
13122         { -1.0f,  1.0f, 0.0f, 0xffff0000},
13123         {  1.0f,  1.0f, 1.0f, 0xffff0000},
13124         { -1.0f, -1.0f, 0.0f, 0xffff0000},
13125         {  1.0f, -1.0f, 1.0f, 0xffff0000},
13126     },
13127     quad_2[] =
13128     {
13129         { -1.0f,  1.0f, 1.0f, 0xff0000ff},
13130         {  1.0f,  1.0f, 0.0f, 0xff0000ff},
13131         { -1.0f, -1.0f, 1.0f, 0xff0000ff},
13132         {  1.0f, -1.0f, 0.0f, 0xff0000ff},
13133     };
13134     static const struct
13135     {
13136         UINT x, y;
13137         D3DCOLOR color;
13138     }
13139     expected_colors[] =
13140     {
13141         { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13142         {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13143         {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13144         {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13145         { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13146         {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
13147         {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13148         {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
13149     };
13150
13151     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13152             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13153     if (FAILED(hr))
13154     {
13155         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
13156         return;
13157     }
13158     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13159             D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13160     if (FAILED(hr))
13161     {
13162         skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
13163         return;
13164     }
13165
13166     ZeroMemory(&present_parameters, sizeof(present_parameters));
13167     present_parameters.Windowed = TRUE;
13168     present_parameters.hDeviceWindow = create_window();
13169     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13170     present_parameters.BackBufferWidth = 640;
13171     present_parameters.BackBufferHeight = 480;
13172     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13173     present_parameters.EnableAutoDepthStencil = TRUE;
13174     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13175     present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13176
13177     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13178             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13179             &present_parameters, &device);
13180     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13181
13182     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13183     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13184     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13185     {
13186         skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
13187         goto cleanup;
13188     }
13189
13190     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13191             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13192     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13193     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13194             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13195     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13196
13197     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13198     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13199     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13200     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13201
13202     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13203     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13204     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13205     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13206     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13207     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13208     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13209     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13210     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13211     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13212
13213     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13214     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13215
13216     /* Render onscreen and then offscreen */
13217     hr = IDirect3DDevice9_BeginScene(device);
13218     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13219     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13220     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13221     hr = IDirect3DDevice9_EndScene(device);
13222     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13223
13224     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
13225     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13226     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13227     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13228
13229     hr = IDirect3DDevice9_BeginScene(device);
13230     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13231     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13232     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13233     hr = IDirect3DDevice9_EndScene(device);
13234     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13235
13236     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
13237     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13238
13239     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13240     {
13241         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13242         ok(color_match(color, expected_colors[i].color, 1),
13243                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13244                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13245     }
13246
13247     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13248     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13249     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13250     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13251
13252     /* Render offscreen and then onscreen */
13253     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13254     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13255     IDirect3DSurface9_Release(ds);
13256     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13257             D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13258     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13259     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13260
13261     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13262     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13263
13264     hr = IDirect3DDevice9_BeginScene(device);
13265     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13266     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13267     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13268     hr = IDirect3DDevice9_EndScene(device);
13269     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13270
13271     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13272     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13273     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13274     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13275
13276     hr = IDirect3DDevice9_BeginScene(device);
13277     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13278     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13279     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13280     hr = IDirect3DDevice9_EndScene(device);
13281     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13282
13283     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13284     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13285
13286     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13287     {
13288         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13289         ok(color_match(color, expected_colors[i].color, 1),
13290                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13291                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13292     }
13293
13294     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13295     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13296
13297     IDirect3DSurface9_Release(ds);
13298     IDirect3DSurface9_Release(readback);
13299     IDirect3DSurface9_Release(rt);
13300     IDirect3DSurface9_Release(original_rt);
13301     cleanup_device(device);
13302
13303     ZeroMemory(&present_parameters, sizeof(present_parameters));
13304     present_parameters.Windowed = TRUE;
13305     present_parameters.hDeviceWindow = create_window();
13306     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13307     present_parameters.BackBufferWidth = 640;
13308     present_parameters.BackBufferHeight = 480;
13309     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13310     present_parameters.EnableAutoDepthStencil = TRUE;
13311     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13312     present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13313
13314     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13315             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
13316             &present_parameters, &device);
13317     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13318
13319     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
13320     ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
13321
13322     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13323             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13324     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13325     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13326             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13327     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13328     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13329             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
13330     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13331
13332     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13333     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13334     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13335     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13336     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13337     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13338     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13339     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13340
13341     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13342     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13343     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13344     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13345     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13346     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13347     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13348     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13349     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13350     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13351
13352     /* Render to a multisampled offscreen frame buffer and then blit to
13353      * the onscreen (not multisampled) frame buffer. */
13354     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13355     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13356
13357     hr = IDirect3DDevice9_BeginScene(device);
13358     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13359     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
13360     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13361     hr = IDirect3DDevice9_EndScene(device);
13362     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13363
13364     hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
13365     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13366     hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
13367     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13368
13369     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13370     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13371     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
13372     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13373
13374     hr = IDirect3DDevice9_BeginScene(device);
13375     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13376     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
13377     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13378     hr = IDirect3DDevice9_EndScene(device);
13379     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13380
13381     hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
13382     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13383
13384     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13385     {
13386         D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
13387         if (i % 4 < 2)
13388             todo_wine ok(color_match(color, expected_colors[i].color, 1),
13389                     "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13390                     expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13391         else
13392             ok(color_match(color, expected_colors[i].color, 1),
13393                     "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13394                     expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13395     }
13396
13397     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13398     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13399
13400     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13401     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13402     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13403     ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
13404
13405     IDirect3DSurface9_Release(original_ds);
13406     IDirect3DSurface9_Release(original_rt);
13407     IDirect3DSurface9_Release(ds);
13408     IDirect3DSurface9_Release(readback);
13409     IDirect3DSurface9_Release(rt);
13410 cleanup:
13411     cleanup_device(device);
13412 }
13413
13414 static void resz_test(IDirect3D9 *d3d9)
13415 {
13416     IDirect3DDevice9 *device = 0;
13417     IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
13418     D3DCAPS9 caps;
13419     HRESULT hr;
13420     D3DPRESENT_PARAMETERS present_parameters;
13421     unsigned int i;
13422     static const DWORD ps_code[] =
13423     {
13424         0xffff0200,                                                             /* ps_2_0                       */
13425         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
13426         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
13427         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
13428         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
13429         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
13430         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
13431         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
13432         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
13433         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
13434         0x0000ffff,                                                             /* end                          */
13435     };
13436     struct
13437     {
13438         float x, y, z;
13439         float s, t, p, q;
13440     }
13441     quad[] =
13442     {
13443         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13444         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13445         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13446         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13447     };
13448     struct
13449     {
13450         UINT x, y;
13451         D3DCOLOR color;
13452     }
13453     expected_colors[] =
13454     {
13455         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13456         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13457         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13458         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13459         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13460         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13461         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13462         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13463     };
13464     IDirect3DTexture9 *texture;
13465     IDirect3DPixelShader9 *ps;
13466     DWORD value;
13467
13468     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13469             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13470     if (FAILED(hr))
13471     {
13472         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
13473         return;
13474     }
13475     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
13476             D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
13477     if (FAILED(hr))
13478     {
13479         skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
13480         return;
13481     }
13482
13483     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13484             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
13485     if (FAILED(hr))
13486     {
13487         skip("No INTZ support, skipping RESZ test.\n");
13488         return;
13489     }
13490
13491     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13492             D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'));
13493     if (FAILED(hr))
13494     {
13495         skip("No RESZ support, skipping RESZ test.\n");
13496         return;
13497     }
13498
13499     ZeroMemory(&present_parameters, sizeof(present_parameters));
13500     present_parameters.Windowed = TRUE;
13501     present_parameters.hDeviceWindow = create_window();
13502     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13503     present_parameters.BackBufferWidth = 640;
13504     present_parameters.BackBufferHeight = 480;
13505     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13506     present_parameters.EnableAutoDepthStencil = FALSE;
13507     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13508     present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
13509
13510     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13511             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13512     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13513
13514     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13515     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13516     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
13517     {
13518         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
13519         cleanup_device(device);
13520         return;
13521     }
13522     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13523     {
13524         skip("No unconditional NP2 texture support, skipping INTZ test.\n");
13525         cleanup_device(device);
13526         return;
13527     }
13528
13529     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13530     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13531
13532     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13533             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
13534     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
13535     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13536             D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
13537     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13538             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13539     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13540
13541     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13542             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13543     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13544     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13545     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13546     hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13547     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13548     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13549     ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13550     IDirect3DSurface9_Release(intz_ds);
13551     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13552     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13553
13554     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13555     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13556     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13557     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13558     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13559     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13560     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13561     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13562     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13563     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13564
13565     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13566     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13567     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13568     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13569     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13570     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13571     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13572     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13573     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13574     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13575
13576     /* Render offscreen (multisampled), blit the depth buffer
13577      * into the INTZ texture and then check its contents */
13578     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13579     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13580     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13581     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13582     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13583     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13584
13585     hr = IDirect3DDevice9_BeginScene(device);
13586     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13587     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13588     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13589
13590     /* The destination depth texture has to be bound to sampler 0 */
13591     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13592     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13593
13594     /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
13595     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13596     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13597     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13598     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13599     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13600     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13601     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13602     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13603     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13604     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13605     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13606     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13607     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13608     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13609
13610     /* The actual multisampled depth buffer resolve happens here */
13611     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13612     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13613     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13614     ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13615
13616     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13617     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13618     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13619     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13620
13621     /* Read the depth values back */
13622     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13623     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13624     hr = IDirect3DDevice9_EndScene(device);
13625     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13626
13627     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13628     {
13629         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13630         ok(color_match(color, expected_colors[i].color, 1),
13631                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13632                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13633     }
13634
13635     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13636     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13637
13638     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13639     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13640     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13641     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13642     IDirect3DSurface9_Release(ds);
13643     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13644     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13645     IDirect3DTexture9_Release(texture);
13646     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13647     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13648     IDirect3DPixelShader9_Release(ps);
13649     IDirect3DSurface9_Release(readback);
13650     IDirect3DSurface9_Release(original_rt);
13651     IDirect3DSurface9_Release(rt);
13652     cleanup_device(device);
13653
13654
13655     ZeroMemory(&present_parameters, sizeof(present_parameters));
13656     present_parameters.Windowed = TRUE;
13657     present_parameters.hDeviceWindow = create_window();
13658     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13659     present_parameters.BackBufferWidth = 640;
13660     present_parameters.BackBufferHeight = 480;
13661     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13662     present_parameters.EnableAutoDepthStencil = TRUE;
13663     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13664     present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13665
13666     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13667             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
13668     ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
13669
13670     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13671     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
13672     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
13673     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
13674     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13675             D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
13676     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
13677     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13678             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13679     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13680     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
13681     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13682     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13683     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13684     hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
13685     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13686     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13687     ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
13688     IDirect3DSurface9_Release(intz_ds);
13689     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13690     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13691
13692     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13693     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13694     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13695     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13696     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13697     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13698     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13699     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13700     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13701     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13702
13703     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13704     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13705     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13706     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13707     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13708     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13709     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13710     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13711     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13712     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13713
13714     /* Render onscreen, blit the depth buffer into the INTZ texture
13715      * and then check its contents */
13716     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13717     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13718     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13719     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13720     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
13721     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13722
13723     hr = IDirect3DDevice9_BeginScene(device);
13724     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13725     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13726     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13727     hr = IDirect3DDevice9_EndScene(device);
13728     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13729
13730     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13731     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13732
13733     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13734     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13735     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13736     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13737     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13738     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13739     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13740     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13741     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13742     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13743     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13744     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13745     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13746     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13747
13748     /* The actual multisampled depth buffer resolve happens here */
13749     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13750     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13751     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
13752     ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
13753
13754     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13755     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13756     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13757     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13758
13759     /* Read the depth values back */
13760     hr = IDirect3DDevice9_BeginScene(device);
13761     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13762     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13763     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13764     hr = IDirect3DDevice9_EndScene(device);
13765     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13766
13767     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13768     {
13769         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13770         ok(color_match(color, expected_colors[i].color, 1),
13771                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13772                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13773     }
13774
13775     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13776     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13777
13778
13779     /* Test edge cases - try with no texture at all */
13780     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13781     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13782     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13783     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13784
13785     hr = IDirect3DDevice9_BeginScene(device);
13786     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13787     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13788     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13789     hr = IDirect3DDevice9_EndScene(device);
13790     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13791
13792     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13793     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13794
13795     /* With a non-multisampled depth buffer */
13796     IDirect3DSurface9_Release(ds);
13797     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
13798             D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
13799
13800     hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
13801     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13802     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13803     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13804     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13805     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13806
13807     hr = IDirect3DDevice9_BeginScene(device);
13808     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13809     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13810     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13811
13812     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13813     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13814
13815     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13816     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13817     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13818     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13819     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
13820     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13821     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13822     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13823     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13824     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13825     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13826     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13827     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
13828     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13829     hr = IDirect3DDevice9_EndScene(device);
13830     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13831
13832     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13833     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13834
13835     hr = IDirect3DDevice9_SetPixelShader(device, ps);
13836     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13837
13838     /* Read the depth values back. */
13839     hr = IDirect3DDevice9_BeginScene(device);
13840     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13841     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13842     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13843     hr = IDirect3DDevice9_EndScene(device);
13844     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13845
13846     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13847     {
13848         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13849         ok(color_match(color, expected_colors[i].color, 1),
13850                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13851                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13852     }
13853
13854     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13855     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13856
13857     /* Without a current depth-stencil buffer set */
13858     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13859     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13860     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13861     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13862
13863     hr = IDirect3DDevice9_BeginScene(device);
13864     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13865     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13866     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13867     hr = IDirect3DDevice9_EndScene(device);
13868     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13869
13870     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
13871     ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
13872
13873     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13874     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
13875     IDirect3DSurface9_Release(ds);
13876     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13877     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
13878     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13879     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13880     IDirect3DTexture9_Release(texture);
13881     IDirect3DPixelShader9_Release(ps);
13882     IDirect3DSurface9_Release(readback);
13883     IDirect3DSurface9_Release(original_rt);
13884     cleanup_device(device);
13885 }
13886
13887 static void zenable_test(IDirect3DDevice9 *device)
13888 {
13889     static const struct
13890     {
13891         struct vec4 position;
13892         D3DCOLOR diffuse;
13893     }
13894     tquad[] =
13895     {
13896         {{  0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
13897         {{  0.0f,   0.0f, -0.5f, 1.0f}, 0xff00ff00},
13898         {{640.0f, 480.0f,  1.5f, 1.0f}, 0xff00ff00},
13899         {{640.0f,   0.0f,  1.5f, 1.0f}, 0xff00ff00},
13900     };
13901     D3DCOLOR color;
13902     D3DCAPS9 caps;
13903     HRESULT hr;
13904     UINT x, y;
13905     UINT i, j;
13906
13907     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
13908     ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
13909     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13910     ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
13911
13912     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
13913     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13914     hr = IDirect3DDevice9_BeginScene(device);
13915     ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13916     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
13917     ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13918     hr = IDirect3DDevice9_EndScene(device);
13919     ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13920
13921     for (i = 0; i < 4; ++i)
13922     {
13923         for (j = 0; j < 4; ++j)
13924         {
13925             x = 80 * ((2 * j) + 1);
13926             y = 60 * ((2 * i) + 1);
13927             color = getPixelColor(device, x, y);
13928             ok(color_match(color, 0x0000ff00, 1),
13929                     "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
13930         }
13931     }
13932
13933     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13934     ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
13935
13936     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13937     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13938
13939     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
13940             && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
13941     {
13942         static const DWORD vs_code[] =
13943         {
13944             0xfffe0101,                                 /* vs_1_1           */
13945             0x0000001f, 0x80000000, 0x900f0000,         /* dcl_position v0  */
13946             0x00000001, 0xc00f0000, 0x90e40000,         /* mov oPos, v0     */
13947             0x00000001, 0xd00f0000, 0x90e40000,         /* mov oD0, v0      */
13948             0x0000ffff
13949         };
13950         static const DWORD ps_code[] =
13951         {
13952             0xffff0101,                                 /* ps_1_1           */
13953             0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
13954             0x0000ffff                                  /* end              */
13955         };
13956         static const struct vec3 quad[] =
13957         {
13958             {-1.0f, -1.0f, -0.5f},
13959             {-1.0f,  1.0f, -0.5f},
13960             { 1.0f, -1.0f,  1.5f},
13961             { 1.0f,  1.0f,  1.5f},
13962         };
13963         static const D3DCOLOR expected[] =
13964         {
13965             0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
13966             0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
13967             0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
13968             0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
13969         };
13970
13971         IDirect3DVertexShader9 *vs;
13972         IDirect3DPixelShader9 *ps;
13973
13974         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13975         ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
13976         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
13977         ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
13978         hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13979         ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
13980         hr = IDirect3DDevice9_SetVertexShader(device, vs);
13981         ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13982         hr = IDirect3DDevice9_SetPixelShader(device, ps);
13983         ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
13984
13985         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
13986         ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
13987         hr = IDirect3DDevice9_BeginScene(device);
13988         ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13989         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13990         ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13991         hr = IDirect3DDevice9_EndScene(device);
13992         ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13993
13994         for (i = 0; i < 4; ++i)
13995         {
13996             for (j = 0; j < 4; ++j)
13997             {
13998                 x = 80 * ((2 * j) + 1);
13999                 y = 60 * ((2 * i) + 1);
14000                 color = getPixelColor(device, x, y);
14001                 ok(color_match(color, expected[i * 4 + j], 1),
14002                         "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
14003             }
14004         }
14005
14006         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14007         ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
14008
14009         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14010         ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
14011         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
14012         ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
14013         IDirect3DPixelShader9_Release(ps);
14014         IDirect3DVertexShader9_Release(vs);
14015     }
14016 }
14017
14018 START_TEST(visual)
14019 {
14020     IDirect3D9 *d3d9;
14021     IDirect3DDevice9 *device_ptr;
14022     D3DCAPS9 caps;
14023     HRESULT hr;
14024     DWORD color;
14025
14026     d3d9_handle = LoadLibraryA("d3d9.dll");
14027     if (!d3d9_handle)
14028     {
14029         skip("Could not load d3d9.dll\n");
14030         return;
14031     }
14032
14033     device_ptr = init_d3d9();
14034     if (!device_ptr)
14035     {
14036         skip("Creating the device failed\n");
14037         return;
14038     }
14039
14040     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
14041
14042     /* Check for the reliability of the returned data */
14043     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
14044     if(FAILED(hr))
14045     {
14046         skip("Clear failed, can't assure correctness of the test results, skipping\n");
14047         goto cleanup;
14048     }
14049
14050     color = getPixelColor(device_ptr, 1, 1);
14051     if(color !=0x00ff0000)
14052     {
14053         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
14054         goto cleanup;
14055     }
14056     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
14057
14058     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
14059     if(FAILED(hr))
14060     {
14061         skip("Clear failed, can't assure correctness of the test results, skipping\n");
14062         goto cleanup;
14063     }
14064
14065     color = getPixelColor(device_ptr, 639, 479);
14066     if(color != 0x0000ddee)
14067     {
14068         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
14069         goto cleanup;
14070     }
14071     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
14072
14073     /* Now execute the real tests */
14074     depth_clamp_test(device_ptr);
14075     stretchrect_test(device_ptr);
14076     lighting_test(device_ptr);
14077     clear_test(device_ptr);
14078     color_fill_test(device_ptr);
14079     fog_test(device_ptr);
14080     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
14081     {
14082         test_cube_wrap(device_ptr);
14083     } else {
14084         skip("No cube texture support\n");
14085     }
14086     z_range_test(device_ptr);
14087     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
14088     {
14089         maxmip_test(device_ptr);
14090     }
14091     else
14092     {
14093         skip("No mipmap support\n");
14094     }
14095     offscreen_test(device_ptr);
14096     ds_size_test(device_ptr);
14097     alpha_test(device_ptr);
14098     shademode_test(device_ptr);
14099     srgbtexture_test(device_ptr);
14100     release_buffer_test(device_ptr);
14101     float_texture_test(device_ptr);
14102     g16r16_texture_test(device_ptr);
14103     pixelshader_blending_test(device_ptr);
14104     texture_transform_flags_test(device_ptr);
14105     autogen_mipmap_test(device_ptr);
14106     fixed_function_decl_test(device_ptr);
14107     conditional_np2_repeat_test(device_ptr);
14108     fixed_function_bumpmap_test(device_ptr);
14109     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
14110         stencil_cull_test(device_ptr);
14111     } else {
14112         skip("No two sided stencil support\n");
14113     }
14114     pointsize_test(device_ptr);
14115     tssargtemp_test(device_ptr);
14116     np2_stretch_rect_test(device_ptr);
14117     yuv_color_test(device_ptr);
14118     zwriteenable_test(device_ptr);
14119     alphatest_test(device_ptr);
14120     viewport_test(device_ptr);
14121
14122     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
14123     {
14124         test_constant_clamp_vs(device_ptr);
14125         test_compare_instructions(device_ptr);
14126     }
14127     else skip("No vs_1_1 support\n");
14128
14129     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
14130     {
14131         test_mova(device_ptr);
14132         loop_index_test(device_ptr);
14133         sincos_test(device_ptr);
14134         sgn_test(device_ptr);
14135         clip_planes_test(device_ptr);
14136         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14137             test_vshader_input(device_ptr);
14138             test_vshader_float16(device_ptr);
14139             stream_test(device_ptr);
14140         } else {
14141             skip("No vs_3_0 support\n");
14142         }
14143     }
14144     else skip("No vs_2_0 support\n");
14145
14146     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0) && caps.PixelShaderVersion >= D3DPS_VERSION(2, 0))
14147     {
14148         fog_with_shader_test(device_ptr);
14149     }
14150     else skip("No vs_2_0 and ps_2_0 support\n");
14151
14152     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
14153     {
14154         texbem_test(device_ptr);
14155         texdepth_test(device_ptr);
14156         texkill_test(device_ptr);
14157         x8l8v8u8_test(device_ptr);
14158         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
14159             constant_clamp_ps_test(device_ptr);
14160             cnd_test(device_ptr);
14161             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
14162                 dp2add_ps_test(device_ptr);
14163                 unbound_sampler_test(device_ptr);
14164                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
14165                     nested_loop_test(device_ptr);
14166                     pretransformed_varying_test(device_ptr);
14167                     vFace_register_test(device_ptr);
14168                     vpos_register_test(device_ptr);
14169                     multiple_rendertargets_test(device_ptr);
14170                 } else {
14171                     skip("No ps_3_0 or vs_3_0 support\n");
14172                 }
14173             } else {
14174                 skip("No ps_2_0 support\n");
14175             }
14176         }
14177     }
14178     else skip("No ps_1_1 support\n");
14179
14180     texop_test(device_ptr);
14181     texop_range_test(device_ptr);
14182     alphareplicate_test(device_ptr);
14183     dp3_alpha_test(device_ptr);
14184     depth_buffer_test(device_ptr);
14185     depth_buffer2_test(device_ptr);
14186     depth_blit_test(device_ptr);
14187     intz_test(device_ptr);
14188     shadow_test(device_ptr);
14189     fp_special_test(device_ptr);
14190     depth_bounds_test(device_ptr);
14191     srgbwrite_format_test(device_ptr);
14192     update_surface_test(device_ptr);
14193     multisample_get_rtdata_test(device_ptr);
14194     zenable_test(device_ptr);
14195
14196     hr = IDirect3DDevice9_GetDirect3D(device_ptr, &d3d9);
14197     ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
14198     cleanup_device(device_ptr);
14199     device_ptr = NULL;
14200
14201     multisampled_depth_buffer_test(d3d9);
14202     resz_test(d3d9);
14203
14204     IDirect3D9_Release(d3d9);
14205
14206 cleanup:
14207     cleanup_device(device_ptr);
14208 }