winealsa: Fix AudioRenderClient Get/ReleaseBuffer protocol.
[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 static HWND create_window(void)
38 {
39     WNDCLASS wc = {0};
40     HWND ret;
41     wc.lpfnWndProc = DefWindowProc;
42     wc.lpszClassName = "d3d9_test_wc";
43     RegisterClass(&wc);
44
45     ret = CreateWindow("d3d9_test_wc", "d3d9_test",
46                         WS_SYSMENU | WS_POPUP , 0, 0, 640, 480, 0, 0, 0, 0);
47     ShowWindow(ret, SW_SHOW);
48     return ret;
49 }
50
51 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
52 {
53     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
54     c1 >>= 8; c2 >>= 8;
55     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56     c1 >>= 8; c2 >>= 8;
57     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
58     c1 >>= 8; c2 >>= 8;
59     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
60     return TRUE;
61 }
62
63 /* Locks a given surface and returns the color at (x,y).  It's the caller's
64  * responsibility to only pass in lockable surfaces and valid x,y coordinates */
65 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
66 {
67     DWORD color;
68     HRESULT hr;
69     D3DSURFACE_DESC desc;
70     RECT rectToLock = {x, y, x+1, y+1};
71     D3DLOCKED_RECT lockedRect;
72
73     hr = IDirect3DSurface9_GetDesc(surface, &desc);
74     if(FAILED(hr))  /* This is not a test */
75     {
76         trace("Can't get the surface description, hr=%08x\n", hr);
77         return 0xdeadbeef;
78     }
79
80     hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
81     if(FAILED(hr))  /* This is not a test */
82     {
83         trace("Can't lock the surface, hr=%08x\n", hr);
84         return 0xdeadbeef;
85     }
86     switch(desc.Format) {
87         case D3DFMT_A8R8G8B8:
88         {
89             color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
90             break;
91         }
92         default:
93             trace("Error: unknown surface format: %d\n", desc.Format);
94             color = 0xdeadbeef;
95             break;
96     }
97     hr = IDirect3DSurface9_UnlockRect(surface);
98     if(FAILED(hr))
99     {
100         trace("Can't unlock the surface, hr=%08x\n", hr);
101     }
102     return color;
103 }
104
105 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
106 {
107     DWORD ret;
108     IDirect3DSurface9 *surf = NULL, *target = NULL;
109     HRESULT hr;
110     D3DLOCKED_RECT lockedRect;
111     RECT rectToLock = {x, y, x+1, y+1};
112
113     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480,
114             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
115     if (FAILED(hr) || !surf)
116     {
117         trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
118         return 0xdeadbeef;
119     }
120
121     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
122     if(FAILED(hr))
123     {
124         trace("Can't get the render target, hr=%08x\n", hr);
125         ret = 0xdeadbeed;
126         goto out;
127     }
128
129     hr = IDirect3DDevice9_GetRenderTargetData(device, target, surf);
130     if (FAILED(hr))
131     {
132         trace("Can't read the render target data, hr=%08x\n", hr);
133         ret = 0xdeadbeec;
134         goto out;
135     }
136
137     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
138     if(FAILED(hr))
139     {
140         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
141         ret = 0xdeadbeeb;
142         goto out;
143     }
144
145     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
146      * really important for these tests
147      */
148     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
149     hr = IDirect3DSurface9_UnlockRect(surf);
150     if(FAILED(hr))
151     {
152         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
153     }
154
155 out:
156     if(target) IDirect3DSurface9_Release(target);
157     if(surf) IDirect3DSurface9_Release(surf);
158     return ret;
159 }
160
161 static IDirect3DDevice9 *init_d3d9(void)
162 {
163     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
164     IDirect3D9 *d3d9_ptr = 0;
165     IDirect3DDevice9 *device_ptr = 0;
166     D3DPRESENT_PARAMETERS present_parameters;
167     HRESULT hr;
168     D3DADAPTER_IDENTIFIER9 identifier;
169
170     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
171     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
172     if (!d3d9_create) return NULL;
173
174     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
175     if (!d3d9_ptr)
176     {
177         win_skip("could not create D3D9\n");
178         return NULL;
179     }
180
181     ZeroMemory(&present_parameters, sizeof(present_parameters));
182     present_parameters.Windowed = TRUE;
183     present_parameters.hDeviceWindow = create_window();
184     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
185     present_parameters.BackBufferWidth = 640;
186     present_parameters.BackBufferHeight = 480;
187     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
188     present_parameters.EnableAutoDepthStencil = TRUE;
189     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
190
191     memset(&identifier, 0, sizeof(identifier));
192     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
193     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
194     trace("Driver string: \"%s\"\n", identifier.Driver);
195     trace("Description string: \"%s\"\n", identifier.Description);
196     ok(identifier.Description[0] != '\0', "Empty driver description\n");
197     trace("Device name string: \"%s\"\n", identifier.DeviceName);
198     ok(identifier.DeviceName[0]  != '\0', "Empty device name\n");
199     trace("Driver version %d.%d.%d.%d\n",
200           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
201           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
202
203     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
204             present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
205     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
206             "Failed to create a device, hr %#x.\n", hr);
207
208     return device_ptr;
209 }
210
211 struct vertex
212 {
213     float x, y, z;
214     DWORD diffuse;
215 };
216
217 struct tvertex
218 {
219     float x, y, z, rhw;
220     DWORD diffuse;
221 };
222
223 struct nvertex
224 {
225     float x, y, z;
226     float nx, ny, nz;
227     DWORD diffuse;
228 };
229
230 static void lighting_test(IDirect3DDevice9 *device)
231 {
232     HRESULT hr;
233     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
234     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
235     DWORD color;
236     D3DMATERIAL9 material, old_material;
237     DWORD cop, carg;
238     DWORD old_colorwrite;
239
240     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
241                       0.0f, 1.0f, 0.0f, 0.0f,
242                       0.0f, 0.0f, 1.0f, 0.0f,
243                       0.0f, 0.0f, 0.0f, 1.0f };
244
245     struct vertex unlitquad[] =
246     {
247         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
248         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
249         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
250         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
251     };
252     struct vertex litquad[] =
253     {
254         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
255         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
256         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
257         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
258     };
259     struct nvertex unlitnquad[] =
260     {
261         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
262         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
263         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
264         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
265     };
266     struct nvertex litnquad[] =
267     {
268         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
269         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
270         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
271         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
272     };
273     WORD Indices[] = {0, 1, 2, 2, 3, 0};
274
275     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
276     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
277
278     /* Setup some states that may cause issues */
279     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
280     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
281     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
282     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
283     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
284     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
285     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
286     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
287     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
288     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
289     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
290     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
291     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
292     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
293     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
294     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
295     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
296     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
297     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
298     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
299     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
300     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
301     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &old_colorwrite);
302     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
303     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
304     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
305
306     hr = IDirect3DDevice9_SetFVF(device, 0);
307     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
308
309     hr = IDirect3DDevice9_SetFVF(device, fvf);
310     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
311
312     hr = IDirect3DDevice9_BeginScene(device);
313     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
314     if(hr == D3D_OK)
315     {
316         /* No lights are defined... That means, lit vertices should be entirely black */
317         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
318         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
319         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
320                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
321         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
322
323         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
324         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
325         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
326                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
327         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
328
329         hr = IDirect3DDevice9_SetFVF(device, nfvf);
330         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
331
332         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
333         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
334         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
335                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
336         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
337
338         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
339         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
340         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
341                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
342         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
343
344         IDirect3DDevice9_EndScene(device);
345         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
346     }
347
348     color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
349     ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
350     color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
351     ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
352     color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
353     ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
354     color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
355     ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
356
357     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
358
359     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
360     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
361     memset(&material, 0, sizeof(material));
362     material.Diffuse.r = 0.0;
363     material.Diffuse.g = 0.0;
364     material.Diffuse.b = 0.0;
365     material.Diffuse.a = 1.0;
366     material.Ambient.r = 0.0;
367     material.Ambient.g = 0.0;
368     material.Ambient.b = 0.0;
369     material.Ambient.a = 0.0;
370     material.Specular.r = 0.0;
371     material.Specular.g = 0.0;
372     material.Specular.b = 0.0;
373     material.Specular.a = 0.0;
374     material.Emissive.r = 0.0;
375     material.Emissive.g = 0.0;
376     material.Emissive.b = 0.0;
377     material.Emissive.a = 0.0;
378     material.Power = 0.0;
379     IDirect3DDevice9_SetMaterial(device, &material);
380     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
381
382     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
383     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
384     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
385     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
386
387     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
388     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
389     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
390     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
391     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
392     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
393     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
394     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
395
396     hr = IDirect3DDevice9_BeginScene(device);
397     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
398     if(SUCCEEDED(hr)) {
399         struct vertex lighting_test[] = {
400             {-1.0,   -1.0,   0.1,    0x8000ff00},
401             { 1.0,   -1.0,   0.1,    0x80000000},
402             {-1.0,    1.0,   0.1,    0x8000ff00},
403             { 1.0,    1.0,   0.1,    0x80000000}
404         };
405         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
406         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
407         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
408         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
409
410         hr = IDirect3DDevice9_EndScene(device);
411         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
412     }
413
414     color = getPixelColor(device, 320, 240);
415     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
416     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
417
418     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
419     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
420     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
421     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
422     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
423     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
424     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
425     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
426     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, old_colorwrite);
427     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
428     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
429     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
430     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
431     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
432 }
433
434 static void clear_test(IDirect3DDevice9 *device)
435 {
436     /* Tests the correctness of clearing parameters */
437     HRESULT hr;
438     D3DRECT rect[2];
439     D3DRECT rect_negneg;
440     DWORD color;
441     D3DVIEWPORT9 old_vp, vp;
442     RECT scissor;
443     DWORD oldColorWrite;
444     BOOL invalid_clear_failed = FALSE;
445
446     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
447     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
448
449     /* Positive x, negative y */
450     rect[0].x1 = 0;
451     rect[0].y1 = 480;
452     rect[0].x2 = 320;
453     rect[0].y2 = 240;
454
455     /* Positive x, positive y */
456     rect[1].x1 = 0;
457     rect[1].y1 = 0;
458     rect[1].x2 = 320;
459     rect[1].y2 = 240;
460     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
461      * returns D3D_OK, but ignores the rectangle silently
462      */
463     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
464     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
465     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
466
467     /* negative x, negative y */
468     rect_negneg.x1 = 640;
469     rect_negneg.y1 = 240;
470     rect_negneg.x2 = 320;
471     rect_negneg.y2 = 0;
472     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
473     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
474     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
475
476     color = getPixelColor(device, 160, 360); /* lower left quad */
477     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
478     color = getPixelColor(device, 160, 120); /* upper left quad */
479     if(invalid_clear_failed) {
480         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
481         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
482     } else {
483         /* If the negative rectangle was dropped silently, the correct ones are cleared */
484         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
485     }
486     color = getPixelColor(device, 480, 360); /* lower right quad  */
487     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
488     color = getPixelColor(device, 480, 120); /* upper right quad */
489     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
490
491     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
492
493     /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
494      * clear the red quad in the top left part of the render target. For some reason it
495      * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
496      * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
497      * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
498      * pick some obvious value
499      */
500     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
501     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
502
503     /* Test how the viewport affects clears */
504     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
505     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
506     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
507     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
508
509     vp.X = 160;
510     vp.Y = 120;
511     vp.Width = 160;
512     vp.Height = 120;
513     vp.MinZ = 0.0;
514     vp.MaxZ = 1.0;
515     hr = IDirect3DDevice9_SetViewport(device, &vp);
516     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
517     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
518     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
519
520     vp.X = 320;
521     vp.Y = 240;
522     vp.Width = 320;
523     vp.Height = 240;
524     vp.MinZ = 0.0;
525     vp.MaxZ = 1.0;
526     hr = IDirect3DDevice9_SetViewport(device, &vp);
527     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
528     rect[0].x1 = 160;
529     rect[0].y1 = 120;
530     rect[0].x2 = 480;
531     rect[0].y2 = 360;
532     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
533     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
534
535     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
536     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
537
538     color = getPixelColor(device, 158, 118);
539     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
540     color = getPixelColor(device, 162, 118);
541     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
542     color = getPixelColor(device, 158, 122);
543     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
544     color = getPixelColor(device, 162, 122);
545     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
546
547     color = getPixelColor(device, 318, 238);
548     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
549     color = getPixelColor(device, 322, 238);
550     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
551     color = getPixelColor(device, 318, 242);
552     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
553     color = getPixelColor(device, 322, 242);
554     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
555
556     color = getPixelColor(device, 478, 358);
557     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
558     color = getPixelColor(device, 482, 358);
559     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
560     color = getPixelColor(device, 478, 362);
561     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
562     color = getPixelColor(device, 482, 362);
563     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
564
565     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
566
567     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
568     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
569
570     scissor.left = 160;
571     scissor.right = 480;
572     scissor.top = 120;
573     scissor.bottom = 360;
574     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
575     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
576     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
577     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
578
579     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
580     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
581     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
582     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
583
584     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
585     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
586
587     color = getPixelColor(device, 158, 118);
588     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
589     color = getPixelColor(device, 162, 118);
590     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
591     color = getPixelColor(device, 158, 122);
592     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
593     color = getPixelColor(device, 162, 122);
594     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
595
596     color = getPixelColor(device, 158, 358);
597     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
598     color = getPixelColor(device, 162, 358);
599     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
600     color = getPixelColor(device, 158, 358);
601     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
602     color = getPixelColor(device, 162, 362);
603     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
604
605     color = getPixelColor(device, 478, 118);
606     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
607     color = getPixelColor(device, 478, 122);
608     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
609     color = getPixelColor(device, 482, 122);
610     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
611     color = getPixelColor(device, 482, 358);
612     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
613
614     color = getPixelColor(device, 478, 358);
615     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
616     color = getPixelColor(device, 478, 362);
617     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
618     color = getPixelColor(device, 482, 358);
619     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
620     color = getPixelColor(device, 482, 362);
621     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
622
623     color = getPixelColor(device, 318, 238);
624     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
625     color = getPixelColor(device, 318, 242);
626     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
627     color = getPixelColor(device, 322, 238);
628     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
629     color = getPixelColor(device, 322, 242);
630     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
631
632     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
633
634     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
635     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
636     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
637     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
638
639     /* Same nvidia windows driver trouble with white clears as earlier in the same test */
640     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
641     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
642
643     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
644     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
645
646     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
647     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
648
649     /* Colorwriteenable does not affect the clear */
650     color = getPixelColor(device, 320, 240);
651     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
652
653     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
654 }
655
656 static void color_fill_test(IDirect3DDevice9 *device)
657 {
658     HRESULT hr;
659     IDirect3DSurface9 *backbuffer = NULL;
660     IDirect3DSurface9 *rt_surface = NULL;
661     IDirect3DSurface9 *offscreen_surface = NULL;
662     DWORD fill_color, color;
663
664     /* Test ColorFill on a the backbuffer (should pass) */
665     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
666     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
667     if(backbuffer)
668     {
669         fill_color = 0x112233;
670         hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
671         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
672
673         color = getPixelColor(device, 0, 0);
674         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
675
676         IDirect3DSurface9_Release(backbuffer);
677     }
678
679     /* Test ColorFill on a render target surface (should pass) */
680     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
681     ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
682     if(rt_surface)
683     {
684         fill_color = 0x445566;
685         hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
686         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
687
688         color = getPixelColorFromSurface(rt_surface, 0, 0);
689         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
690
691         IDirect3DSurface9_Release(rt_surface);
692     }
693
694     /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
695     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
696             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
697     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
698     if(offscreen_surface)
699     {
700         fill_color = 0x778899;
701         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
702         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
703
704         color = getPixelColorFromSurface(offscreen_surface, 0, 0);
705         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
706
707         IDirect3DSurface9_Release(offscreen_surface);
708     }
709
710     /* Try ColorFill on a offscreen surface in sysmem (should fail) */
711     offscreen_surface = NULL;
712     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
713             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
714     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
715     if(offscreen_surface)
716     {
717         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
718         ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
719
720         IDirect3DSurface9_Release(offscreen_surface);
721     }
722 }
723
724 typedef struct {
725     float in[4];
726     DWORD out;
727 } test_data_t;
728
729 /*
730  *  c7      mova    ARGB            mov     ARGB
731  * -2.4     -2      0x00ffff00      -3      0x00ff0000
732  * -1.6     -2      0x00ffff00      -2      0x00ffff00
733  * -0.4      0      0x0000ffff      -1      0x0000ff00
734  *  0.4      0      0x0000ffff       0      0x0000ffff
735  *  1.6      2      0x00ff00ff       1      0x000000ff
736  *  2.4      2      0x00ff00ff       2      0x00ff00ff
737  */
738 static void test_mova(IDirect3DDevice9 *device)
739 {
740     static const DWORD mova_test[] = {
741         0xfffe0200,                                                             /* vs_2_0                       */
742         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
743         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
744         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
745         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
746         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
747         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
748         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
749         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
750         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
751         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
752         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
753         0x0000ffff                                                              /* END                          */
754     };
755     static const DWORD mov_test[] = {
756         0xfffe0101,                                                             /* vs_1_1                       */
757         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
758         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
759         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
760         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
761         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
762         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
763         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
764         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
765         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
766         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
767         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
768         0x0000ffff                                                              /* END                          */
769     };
770
771     static const test_data_t test_data[2][6] = {
772         {
773             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
774             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
775             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
776             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
777             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
778             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
779         },
780         {
781             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
782             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
783             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
784             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
785             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
786             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
787         }
788     };
789
790     static const float quad[][3] = {
791         {-1.0f, -1.0f, 0.0f},
792         {-1.0f,  1.0f, 0.0f},
793         { 1.0f, -1.0f, 0.0f},
794         { 1.0f,  1.0f, 0.0f},
795     };
796
797     static const D3DVERTEXELEMENT9 decl_elements[] = {
798         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
799         D3DDECL_END()
800     };
801
802     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
803     IDirect3DVertexShader9 *mova_shader = NULL;
804     IDirect3DVertexShader9 *mov_shader = NULL;
805     HRESULT hr;
806     UINT i, j;
807
808     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
809     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
810     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
811     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
812     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
813     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
814     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
815     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
816
817     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
818     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
819     for(j = 0; j < 2; ++j)
820     {
821         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
822         {
823             DWORD color;
824
825             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
826             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
827
828             hr = IDirect3DDevice9_BeginScene(device);
829             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
830
831             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
832             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
833
834             hr = IDirect3DDevice9_EndScene(device);
835             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
836
837             color = getPixelColor(device, 320, 240);
838             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
839                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
840
841             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
842             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
843
844             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
845             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
846         }
847         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
848         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
849     }
850
851     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
852     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
853
854     IDirect3DVertexDeclaration9_Release(vertex_declaration);
855     IDirect3DVertexShader9_Release(mova_shader);
856     IDirect3DVertexShader9_Release(mov_shader);
857 }
858
859 struct sVertex {
860     float x, y, z;
861     DWORD diffuse;
862     DWORD specular;
863 };
864
865 struct sVertexT {
866     float x, y, z, rhw;
867     DWORD diffuse;
868     DWORD specular;
869 };
870
871 static void fog_test(IDirect3DDevice9 *device)
872 {
873     HRESULT hr;
874     D3DCOLOR color;
875     float start = 0.0f, end = 1.0f;
876     D3DCAPS9 caps;
877     int i;
878
879     /* Gets full z based fog with linear fog, no fog with specular color */
880     struct sVertex untransformed_1[] = {
881         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
882         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
883         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
884         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
885     };
886     /* Ok, I am too lazy to deal with transform matrices */
887     struct sVertex untransformed_2[] = {
888         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
889         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
890         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
891         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
892     };
893     /* Untransformed ones. Give them a different diffuse color to make the test look
894      * nicer. It also makes making sure that they are drawn correctly easier.
895      */
896     struct sVertexT transformed_1[] = {
897         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
898         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
899         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
900         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
901     };
902     struct sVertexT transformed_2[] = {
903         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
904         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
905         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
906         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
907     };
908     struct vertex rev_fog_quads[] = {
909        {-1.0,   -1.0,   0.1,    0x000000ff},
910        {-1.0,    0.0,   0.1,    0x000000ff},
911        { 0.0,    0.0,   0.1,    0x000000ff},
912        { 0.0,   -1.0,   0.1,    0x000000ff},
913
914        { 0.0,   -1.0,   0.9,    0x000000ff},
915        { 0.0,    0.0,   0.9,    0x000000ff},
916        { 1.0,    0.0,   0.9,    0x000000ff},
917        { 1.0,   -1.0,   0.9,    0x000000ff},
918
919        { 0.0,    0.0,   0.4,    0x000000ff},
920        { 0.0,    1.0,   0.4,    0x000000ff},
921        { 1.0,    1.0,   0.4,    0x000000ff},
922        { 1.0,    0.0,   0.4,    0x000000ff},
923
924        {-1.0,    0.0,   0.7,    0x000000ff},
925        {-1.0,    1.0,   0.7,    0x000000ff},
926        { 0.0,    1.0,   0.7,    0x000000ff},
927        { 0.0,    0.0,   0.7,    0x000000ff},
928     };
929     WORD Indices[] = {0, 1, 2, 2, 3, 0};
930
931     const float ident_mat[16] =
932     {
933         1.0f, 0.0f, 0.0f, 0.0f,
934         0.0f, 1.0f, 0.0f, 0.0f,
935         0.0f, 0.0f, 1.0f, 0.0f,
936         0.0f, 0.0f, 0.0f, 1.0f
937     };
938     const float world_mat1[16] =
939     {
940         1.0f, 0.0f,  0.0f, 0.0f,
941         0.0f, 1.0f,  0.0f, 0.0f,
942         0.0f, 0.0f,  1.0f, 0.0f,
943         0.0f, 0.0f, -0.5f, 1.0f
944     };
945     const float world_mat2[16] =
946     {
947         1.0f, 0.0f, 0.0f, 0.0f,
948         0.0f, 1.0f, 0.0f, 0.0f,
949         0.0f, 0.0f, 1.0f, 0.0f,
950         0.0f, 0.0f, 1.0f, 1.0f
951     };
952     const float proj_mat[16] =
953     {
954         1.0f, 0.0f,  0.0f, 0.0f,
955         0.0f, 1.0f,  0.0f, 0.0f,
956         0.0f, 0.0f,  1.0f, 0.0f,
957         0.0f, 0.0f, -1.0f, 1.0f
958     };
959
960     const struct sVertex far_quad1[] =
961     {
962         {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
963         {-1.0f,  0.0f, 0.5f, 0xffff0000, 0xff000000},
964         { 0.0f,  0.0f, 0.5f, 0xffff0000, 0xff000000},
965         { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
966     };
967     const struct sVertex far_quad2[] =
968     {
969         {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
970         {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
971         { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
972         { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
973     };
974
975     memset(&caps, 0, sizeof(caps));
976     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
977     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
978     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
979     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
980
981     /* Setup initial states: No lighting, fog on, fog color */
982     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
983     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
984     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
985     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
986     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
987     ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
988
989     /* First test: Both table fog and vertex fog off */
990     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
991     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
992     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
993     ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
994
995     /* Start = 0, end = 1. Should be default, but set them */
996     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
997     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
998     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
999     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1000
1001     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1002     {
1003         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1004         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1005         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
1006         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1007                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1008                                                      sizeof(untransformed_1[0]));
1009         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1010
1011         /* That makes it use the Z value */
1012         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1013         ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
1014         /* Untransformed, vertex fog != none (or table fog != none):
1015          * Use the Z value as input into the equation
1016          */
1017         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1018                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1019                                                      sizeof(untransformed_2[0]));
1020         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1021
1022         /* transformed verts */
1023         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1024         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1025         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1026         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1027                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1028                                                      sizeof(transformed_1[0]));
1029         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1030
1031         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1032         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1033         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
1034          * equation
1035          */
1036         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1037                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
1038                                                      sizeof(transformed_2[0]));
1039         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1040
1041         hr = IDirect3DDevice9_EndScene(device);
1042         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1043     }
1044     else
1045     {
1046         ok(FALSE, "BeginScene failed\n");
1047     }
1048
1049     color = getPixelColor(device, 160, 360);
1050     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1051     color = getPixelColor(device, 160, 120);
1052     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1053     color = getPixelColor(device, 480, 120);
1054     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1055     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1056     {
1057         color = getPixelColor(device, 480, 360);
1058         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1059     }
1060     else
1061     {
1062         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1063          * The settings above result in no fogging with vertex fog
1064          */
1065         color = getPixelColor(device, 480, 120);
1066         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1067         trace("Info: Table fog not supported by this device\n");
1068     }
1069     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1070
1071     /* Now test the special case fogstart == fogend */
1072     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1073     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1074
1075     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1076     {
1077         start = 512;
1078         end = 512;
1079         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1080         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1081         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1082         ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1083
1084         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1085         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1086         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1087         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1088         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1089         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1090
1091         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1092          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1093          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1094          * The third transformed quad remains unfogged because the fogcoords are read from the specular
1095          * color and has fixed fogstart and fogend.
1096          */
1097         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1098                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1099                 sizeof(untransformed_1[0]));
1100         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1101         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1102                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1103                 sizeof(untransformed_2[0]));
1104         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1105
1106         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1107         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1108         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1109         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1110                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1111                 sizeof(transformed_1[0]));
1112         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1113
1114         hr = IDirect3DDevice9_EndScene(device);
1115         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1116     }
1117     else
1118     {
1119         ok(FALSE, "BeginScene failed\n");
1120     }
1121     color = getPixelColor(device, 160, 360);
1122     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1123     color = getPixelColor(device, 160, 120);
1124     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1125     color = getPixelColor(device, 480, 120);
1126     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1127     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1128
1129     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1130      * but without shaders it seems to work everywhere
1131      */
1132     end = 0.2;
1133     start = 0.8;
1134     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1135     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1136     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1137     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1138     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1139     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1140
1141     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1142      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1143      * so skip this for now
1144      */
1145     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1146         const char *mode = (i ? "table" : "vertex");
1147         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1148         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1149         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1150         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1151         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1152         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1153         hr = IDirect3DDevice9_BeginScene(device);
1154         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1155         if(SUCCEEDED(hr)) {
1156             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1157                                 4,  5,  6,  6,  7, 4,
1158                                 8,  9, 10, 10, 11, 8,
1159                             12, 13, 14, 14, 15, 12};
1160
1161             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1162                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1163                     sizeof(rev_fog_quads[0]));
1164             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1165
1166             hr = IDirect3DDevice9_EndScene(device);
1167             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1168         }
1169         color = getPixelColor(device, 160, 360);
1170         ok(color_match(color, 0x0000ff00, 1),
1171                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1172
1173         color = getPixelColor(device, 160, 120);
1174         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1175                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1176
1177         color = getPixelColor(device, 480, 120);
1178         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1179                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1180
1181         color = getPixelColor(device, 480, 360);
1182         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1183
1184         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1185
1186         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1187             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1188             break;
1189         }
1190     }
1191
1192     if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1193     {
1194         /* A simple fog + non-identity world matrix test */
1195         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat1);
1196         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
1197
1198         start = 0.0;
1199         end = 1.0;
1200         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1201         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1202         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1203         ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1204         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1205         ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1206         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1207         ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1208
1209         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1210         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
1211
1212         if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1213         {
1214             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1215             ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1216
1217             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1218                     2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1219             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1220
1221             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1222                     2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1223             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1224
1225             hr = IDirect3DDevice9_EndScene(device);
1226             ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1227         }
1228         else
1229         {
1230             ok(FALSE, "BeginScene failed\n");
1231         }
1232
1233         color = getPixelColor(device, 160, 360);
1234         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
1235                 "Unfogged quad has color %08x\n", color);
1236         color = getPixelColor(device, 160, 120);
1237         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1238                 "Fogged out quad has color %08x\n", color);
1239
1240         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1241
1242         /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
1243         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat2);
1244         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1245         hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)proj_mat);
1246         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1247
1248         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1249         ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1250
1251         if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1252         {
1253             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1254             ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1255
1256             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1257                     2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1258             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1259
1260             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1261                     2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1262             ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1263
1264             hr = IDirect3DDevice9_EndScene(device);
1265             ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1266         }
1267         else
1268         {
1269             ok(FALSE, "BeginScene failed\n");
1270         }
1271
1272         color = getPixelColor(device, 160, 360);
1273         todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1274         color = getPixelColor(device, 160, 120);
1275         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1276                 "Fogged out quad has color %08x\n", color);
1277
1278         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1279
1280         hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)ident_mat);
1281         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1282         hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)ident_mat);
1283         ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1284     }
1285     else
1286     {
1287         skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1288     }
1289
1290     /* Test RANGEFOG vs FOGTABLEMODE */
1291     if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
1292             (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
1293     {
1294         struct sVertex untransformed_3[] =
1295         {
1296             {-1.0,-1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1297             {-1.0, 1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1298             { 1.0,-1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1299             { 1.0, 1.0,   0.4999f,      0xFFFF0000,     0xFF000000  },
1300         };
1301
1302         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1303         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
1304         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1305         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
1306
1307         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
1308         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1309
1310         /* z=0.4999, set the fogstart to 0.5 and fogend slightly higher. If range fog
1311          * is not used, the fog coordinate will be equal to fogstart and the quad not
1312          * fogged. If range fog is used the fog coordinate will be slightly higher and
1313          * the fog coordinate will be > fogend, so we get a fully fogged quad. The fog
1314          * is calculated per vertex and interpolated, so even the center of the screen
1315          * where the difference doesn't matter will be fogged, but check the corners in
1316          * case a d3d/gl implementation decides to calculate the fog factor per fragment */
1317         start = 0.5f;
1318         end = 0.50001f;
1319         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1320         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1321         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1322         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1323
1324         /* Table fog: Range fog is not used */
1325         hr = IDirect3DDevice9_BeginScene(device);
1326         ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
1327         if (SUCCEEDED(hr))
1328         {
1329             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1330             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1331             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1332             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1333             hr = IDirect3DDevice9_EndScene(device);
1334             ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1335         }
1336         color = getPixelColor(device, 10, 10);
1337         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1338         color = getPixelColor(device, 630, 10);
1339         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1340         color = getPixelColor(device, 10, 470);
1341         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1342         color = getPixelColor(device, 630, 470);
1343         ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1344
1345         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1346         ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1347
1348         /* Vertex fog: Rangefog is used */
1349         hr = IDirect3DDevice9_BeginScene(device);
1350         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP returned %#08x\n", hr);
1351         if (SUCCEEDED(hr))
1352         {
1353             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1354             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1355             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1356             ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1357             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1358             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1359             hr = IDirect3DDevice9_EndScene(device);
1360             ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1361         }
1362         color = getPixelColor(device, 10, 10);
1363         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1364                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1365         color = getPixelColor(device, 630, 10);
1366         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1367                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1368         color = getPixelColor(device, 10, 470);
1369         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1370                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1371         color = getPixelColor(device, 630, 470);
1372         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1373                 "Rangefog with vertex fog returned color 0x%08x\n", color);
1374
1375         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1376         ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1377
1378         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
1379         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1380     }
1381     else
1382     {
1383         skip("Range fog or table fog not supported, skipping range fog tests\n");
1384     }
1385
1386     /* Turn off the fog master switch to avoid confusing other tests */
1387     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1388     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1389     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1390     ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1391     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1392     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1393 }
1394
1395 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1396  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1397  * regardless of the actual addressing mode set. The way this test works is
1398  * that we sample in one of the corners of the cubemap with filtering enabled,
1399  * and check the interpolated color. There are essentially two reasonable
1400  * things an implementation can do: Either pick one of the faces and
1401  * interpolate the edge texel with itself (i.e., clamp within the face), or
1402  * interpolate between the edge texels of the three involved faces. It should
1403  * never involve the border color or the other side (texcoord wrapping) of a
1404  * face in the interpolation. */
1405 static void test_cube_wrap(IDirect3DDevice9 *device)
1406 {
1407     static const float quad[][6] = {
1408         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1409         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1410         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1411         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1412     };
1413
1414     static const D3DVERTEXELEMENT9 decl_elements[] = {
1415         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1416         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1417         D3DDECL_END()
1418     };
1419
1420     static const struct {
1421         D3DTEXTUREADDRESS mode;
1422         const char *name;
1423     } address_modes[] = {
1424         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1425         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1426         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1427         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1428         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1429     };
1430
1431     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1432     IDirect3DCubeTexture9 *texture = NULL;
1433     IDirect3DSurface9 *surface = NULL;
1434     IDirect3DSurface9 *face_surface;
1435     D3DLOCKED_RECT locked_rect;
1436     HRESULT hr;
1437     UINT x;
1438     INT y, face;
1439
1440     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1441     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1442     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1443     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1444
1445     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1446             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1447     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1448
1449     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1450             D3DPOOL_DEFAULT, &texture, NULL);
1451     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1452
1453     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1454     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1455
1456     for (y = 0; y < 128; ++y)
1457     {
1458         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1459         for (x = 0; x < 64; ++x)
1460         {
1461             *ptr++ = 0xff0000ff;
1462         }
1463         for (x = 64; x < 128; ++x)
1464         {
1465             *ptr++ = 0xffff0000;
1466         }
1467     }
1468
1469     hr = IDirect3DSurface9_UnlockRect(surface);
1470     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1471
1472     hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1473     ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1474
1475     hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1476     ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1477
1478     IDirect3DSurface9_Release(face_surface);
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++ = 0xffff0000;
1489         }
1490         for (x = 64; x < 128; ++x)
1491         {
1492             *ptr++ = 0xff0000ff;
1493         }
1494     }
1495
1496     hr = IDirect3DSurface9_UnlockRect(surface);
1497     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1498
1499     /* Create cube faces */
1500     for (face = 1; face < 6; ++face)
1501     {
1502         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1503         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1504
1505         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1506         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1507
1508         IDirect3DSurface9_Release(face_surface);
1509     }
1510
1511     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1512     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1513
1514     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1515     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1516     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1517     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1518     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1519     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1520
1521     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1522     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1523
1524     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1525     {
1526         DWORD color;
1527
1528         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1529         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1530         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1531         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1532
1533         hr = IDirect3DDevice9_BeginScene(device);
1534         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1535
1536         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1537         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1538
1539         hr = IDirect3DDevice9_EndScene(device);
1540         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1541
1542         color = getPixelColor(device, 320, 240);
1543         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1544                 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1545                 color, address_modes[x].name);
1546
1547         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1548         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1549
1550         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1551         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1552     }
1553
1554     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1555     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1556
1557     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1558     IDirect3DCubeTexture9_Release(texture);
1559     IDirect3DSurface9_Release(surface);
1560 }
1561
1562 static void offscreen_test(IDirect3DDevice9 *device)
1563 {
1564     HRESULT hr;
1565     IDirect3DTexture9 *offscreenTexture = NULL;
1566     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1567     DWORD color;
1568
1569     static const float quad[][5] = {
1570         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1571         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1572         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1573         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1574     };
1575
1576     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1577     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1578
1579     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1580     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1581     if(!offscreenTexture) {
1582         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1583         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1584         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1585         if(!offscreenTexture) {
1586             skip("Cannot create an offscreen render target\n");
1587             goto out;
1588         }
1589     }
1590
1591     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1592     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1593     if(!backbuffer) {
1594         goto out;
1595     }
1596
1597     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1598     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1599     if(!offscreen) {
1600         goto out;
1601     }
1602
1603     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1604     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1605
1606     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1607     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1608     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1609     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1610     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1611     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1612     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1613     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1614     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1615     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1616
1617     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1618         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1619         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1620         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1621         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1622
1623         /* Draw without textures - Should result in a white quad */
1624         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1625         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1626
1627         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1628         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1629         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1630         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1631
1632         /* This time with the texture */
1633         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1634         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1635
1636         IDirect3DDevice9_EndScene(device);
1637     }
1638
1639     /* Center quad - should be white */
1640     color = getPixelColor(device, 320, 240);
1641     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1642     /* Some quad in the cleared part of the texture */
1643     color = getPixelColor(device, 170, 240);
1644     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1645     /* Part of the originally cleared back buffer */
1646     color = getPixelColor(device, 10, 10);
1647     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1648     if(0) {
1649         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1650          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1651          * the offscreen rendering mode this test would succeed or fail
1652          */
1653         color = getPixelColor(device, 10, 470);
1654         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1655     }
1656
1657     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1658
1659 out:
1660     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1661     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1662
1663     /* restore things */
1664     if(backbuffer) {
1665         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1666         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1667         IDirect3DSurface9_Release(backbuffer);
1668     }
1669     if(offscreenTexture) {
1670         IDirect3DTexture9_Release(offscreenTexture);
1671     }
1672     if(offscreen) {
1673         IDirect3DSurface9_Release(offscreen);
1674     }
1675 }
1676
1677 /* This test tests fog in combination with shaders.
1678  * What's tested: linear fog (vertex and table) with pixel shader
1679  *                linear table fog with non foggy vertex shader
1680  *                vertex fog with foggy vertex shader, non-linear
1681  *                fog with shader, non-linear fog with foggy shader,
1682  *                linear table fog with foggy shader
1683  */
1684 static void fog_with_shader_test(IDirect3DDevice9 *device)
1685 {
1686     HRESULT hr;
1687     DWORD color;
1688     union {
1689         float f;
1690         DWORD i;
1691     } start, end;
1692     unsigned int i, j;
1693
1694     /* basic vertex shader without fog computation ("non foggy") */
1695     static const DWORD vertex_shader_code1[] = {
1696         0xfffe0101,                                                             /* vs_1_1                       */
1697         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1698         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1699         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1700         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1701         0x0000ffff
1702     };
1703     /* basic vertex shader with reversed fog computation ("foggy") */
1704     static const DWORD vertex_shader_code2[] = {
1705         0xfffe0101,                                                             /* vs_1_1                        */
1706         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1707         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1708         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1709         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1710         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1711         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1712         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1713         0x0000ffff
1714     };
1715     /* basic pixel shader */
1716     static const DWORD pixel_shader_code[] = {
1717         0xffff0101,                                                             /* ps_1_1     */
1718         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1719         0x0000ffff
1720     };
1721
1722     static struct vertex quad[] = {
1723         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1724         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1725         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1726         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1727     };
1728
1729     static const D3DVERTEXELEMENT9 decl_elements[] = {
1730         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1731         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1732         D3DDECL_END()
1733     };
1734
1735     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1736     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1737     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1738
1739     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1740     static const struct test_data_t {
1741         int vshader;
1742         int pshader;
1743         D3DFOGMODE vfog;
1744         D3DFOGMODE tfog;
1745         unsigned int color[11];
1746     } test_data[] = {
1747         /* only pixel shader: */
1748         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1749         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1750         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1751         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1752         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1753         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1754         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1755         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1756         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1757         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1758         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1759         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1760         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1761         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1762         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1763
1764         /* vertex shader */
1765         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1766         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1767          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1768         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1769         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1770         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1771         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1772         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1773         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1774
1775         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1776         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1777         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1778         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1779         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1780         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1781
1782         /* vertex shader and pixel shader */
1783         /* The next 4 tests would read the fog coord output, but it isn't available.
1784          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1785          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1786          * These tests should be disabled if some other hardware behaves differently
1787          */
1788         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1789         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1790         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1791         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1792         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1793         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1794         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1795         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1796         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1797         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1798         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1799         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1800
1801         /* These use the Z coordinate with linear table fog */
1802         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1803         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1804         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1805         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1806         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1807         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1808         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1809         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1810         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1811         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1812         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1813         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1814
1815         /* Non-linear table fog without fog coord */
1816         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1817         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1818         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1819         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1820         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1821         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1822
1823 #if 0  /* FIXME: these fail on GeForce 8500 */
1824         /* foggy vertex shader */
1825         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1826         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1827          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1828         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1829         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1830          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1831         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1832         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1833          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1834         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1835         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1836          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1837 #endif
1838
1839         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1840          * all using the fixed fog-coord linear fog
1841          */
1842         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1843         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1844          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1845         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1846         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1847          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1848         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1849         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1850          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1851         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1852         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1853          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1854
1855         /* These use table fog. Here the shader-provided fog coordinate is
1856          * ignored and the z coordinate used instead
1857          */
1858         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1859         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1860         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1861         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1862         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1863         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1864         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1865         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1866         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1867     };
1868
1869     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1870     start.f=0.1f;
1871     end.f=0.9f;
1872
1873     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1874     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1875     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1876     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1877     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1878     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1879     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1880     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1881
1882     /* Setup initial states: No lighting, fog on, fog color */
1883     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1884     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1885     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1886     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1887     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1888     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1889     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1890     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1891
1892     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1893     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1894     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1895     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1896
1897     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1898     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1899     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1900     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1901     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1902
1903     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1904     {
1905         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1906         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1907         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1908         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1909         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1910         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1911         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1912         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1913
1914         for(j=0; j < 11; j++)
1915         {
1916             /* Don't use the whole zrange to prevent rounding errors */
1917             quad[0].z = 0.001f + (float)j / 10.02f;
1918             quad[1].z = 0.001f + (float)j / 10.02f;
1919             quad[2].z = 0.001f + (float)j / 10.02f;
1920             quad[3].z = 0.001f + (float)j / 10.02f;
1921
1922             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1923             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1924
1925             hr = IDirect3DDevice9_BeginScene(device);
1926             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1927
1928             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1929             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1930
1931             hr = IDirect3DDevice9_EndScene(device);
1932             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1933
1934             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1935             color = getPixelColor(device, 128, 240);
1936             ok(color_match(color, test_data[i].color[j], 13),
1937                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1938                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1939
1940             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1941         }
1942     }
1943
1944     /* reset states */
1945     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1946     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1947     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1948     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1949     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1950     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1951     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1952     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1953
1954     IDirect3DVertexShader9_Release(vertex_shader[1]);
1955     IDirect3DVertexShader9_Release(vertex_shader[2]);
1956     IDirect3DPixelShader9_Release(pixel_shader[1]);
1957     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1958 }
1959
1960 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1961     unsigned int i, x, y;
1962     HRESULT hr;
1963     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1964     D3DLOCKED_RECT locked_rect;
1965
1966     /* Generate the textures */
1967     for(i=0; i<2; i++)
1968     {
1969         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1970                                             D3DPOOL_MANAGED, &texture[i], NULL);
1971         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1972
1973         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1974         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1975         for (y = 0; y < 128; ++y)
1976         {
1977             if(i)
1978             { /* Set up black texture with 2x2 texel white spot in the middle */
1979                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1980                 for (x = 0; x < 128; ++x)
1981                 {
1982                     if(y>62 && y<66 && x>62 && x<66)
1983                         *ptr++ = 0xffffffff;
1984                     else
1985                         *ptr++ = 0xff000000;
1986                 }
1987             }
1988             else
1989             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1990                * (if multiplied with bumpenvmat)
1991               */
1992                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1993                 for (x = 0; x < 128; ++x)
1994                 {
1995                     if(abs(x-64)>abs(y-64))
1996                     {
1997                         if(x < 64)
1998                             *ptr++ = 0xc000;
1999                         else
2000                             *ptr++ = 0x4000;
2001                     }
2002                     else
2003                     {
2004                         if(y < 64)
2005                             *ptr++ = 0x0040;
2006                         else
2007                             *ptr++ = 0x00c0;
2008                     }
2009                 }
2010             }
2011         }
2012         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2013         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2014
2015         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2016         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2017
2018         /* Disable texture filtering */
2019         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2020         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2021         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2022         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2023
2024         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2025         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2026         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2027         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2028     }
2029 }
2030
2031 /* test the behavior of the texbem instruction
2032  * with normal 2D and projective 2D textures
2033  */
2034 static void texbem_test(IDirect3DDevice9 *device)
2035 {
2036     HRESULT hr;
2037     DWORD color;
2038     int i;
2039
2040     static const DWORD pixel_shader_code[] = {
2041         0xffff0101,                         /* ps_1_1*/
2042         0x00000042, 0xb00f0000,             /* tex t0*/
2043         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2044         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
2045         0x0000ffff
2046     };
2047     static const DWORD double_texbem_code[] =  {
2048         0xffff0103,                                         /* ps_1_3           */
2049         0x00000042, 0xb00f0000,                             /* tex t0           */
2050         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
2051         0x00000042, 0xb00f0002,                             /* tex t2           */
2052         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
2053         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
2054         0x0000ffff                                          /* end              */
2055     };
2056
2057
2058     static const float quad[][7] = {
2059         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
2060         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
2061         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
2062         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
2063     };
2064     static const float quad_proj[][9] = {
2065         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
2066         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
2067         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
2068         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
2069     };
2070
2071     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
2072         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2073         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2074         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2075         D3DDECL_END()
2076     },{
2077         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2078         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2079         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2080         D3DDECL_END()
2081     } };
2082
2083     /* use asymmetric matrix to test loading */
2084     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
2085
2086     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2087     IDirect3DPixelShader9       *pixel_shader       = NULL;
2088     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
2089     D3DLOCKED_RECT locked_rect;
2090
2091     generate_bumpmap_textures(device);
2092
2093     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2094     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2095     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2096     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2097     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
2098
2099     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2100     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2101
2102     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2103     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2104
2105     for(i=0; i<2; i++)
2106     {
2107         if(i)
2108         {
2109             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
2110             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2111         }
2112
2113         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
2114         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2115         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2116         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2117
2118         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
2119         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2120         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2121         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2122
2123         hr = IDirect3DDevice9_BeginScene(device);
2124         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2125
2126         if(!i)
2127             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2128         else
2129             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
2130         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2131
2132         hr = IDirect3DDevice9_EndScene(device);
2133         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2134
2135         color = getPixelColor(device, 320-32, 240);
2136         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2137         color = getPixelColor(device, 320+32, 240);
2138         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2139         color = getPixelColor(device, 320, 240-32);
2140         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2141         color = getPixelColor(device, 320, 240+32);
2142         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2143
2144         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2145         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2146
2147         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2148         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2149         IDirect3DPixelShader9_Release(pixel_shader);
2150
2151         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2152         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2153         IDirect3DVertexDeclaration9_Release(vertex_declaration);
2154     }
2155
2156     /* clean up */
2157     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2158     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2159
2160     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2161     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2162
2163     for(i=0; i<2; i++)
2164     {
2165         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
2166         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
2167         IDirect3DTexture9_Release(texture); /* For the GetTexture */
2168         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2169         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2170         IDirect3DTexture9_Release(texture);
2171     }
2172
2173     /* Test double texbem */
2174     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
2175     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2176     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
2177     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2178     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
2179     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2180     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
2181     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2182
2183     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
2184     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2185     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
2186     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
2187
2188     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2189     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2190
2191     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
2192     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2193     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
2194     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
2195     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
2196     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2197
2198     {
2199         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
2200 #define tex  0x00ff0000
2201 #define tex1 0x0000ff00
2202 #define origin 0x000000ff
2203         static const DWORD pixel_data[] = {
2204             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2205             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2206             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2207             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2208             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
2209             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2210             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2211             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2212         };
2213 #undef tex1
2214 #undef tex2
2215 #undef origin
2216
2217         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
2218         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2219         for(i = 0; i < 8; i++) {
2220             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
2221         }
2222         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
2223         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2224     }
2225
2226     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2227     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2228     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
2229     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2230     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
2231     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2232     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2233     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2234     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2235     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2236     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2237     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2238
2239     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
2240     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
2241     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2242     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2243     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2244     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2245     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2246     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2247     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2248     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2249
2250     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2251     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2252     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2253     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2254     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2255     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2256     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2257     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2258     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2259     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2260
2261     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2262     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2263     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2264     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2265     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2266     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2267     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2268     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2269     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2270     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2271     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2272     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2273     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2274     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2275     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2276     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2277
2278     hr = IDirect3DDevice9_BeginScene(device);
2279     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2280     if(SUCCEEDED(hr)) {
2281         static const float double_quad[] = {
2282             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2283              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2284             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2285              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2286         };
2287
2288         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2289         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2290         hr = IDirect3DDevice9_EndScene(device);
2291         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2292     }
2293     color = getPixelColor(device, 320, 240);
2294     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2295
2296     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2297     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2298     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2299     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2300     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2301     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2302     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2303     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2304     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2305     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2306
2307     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2308     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2309
2310     IDirect3DPixelShader9_Release(pixel_shader);
2311     IDirect3DTexture9_Release(texture);
2312     IDirect3DTexture9_Release(texture1);
2313     IDirect3DTexture9_Release(texture2);
2314 }
2315
2316 static void z_range_test(IDirect3DDevice9 *device)
2317 {
2318     const struct vertex quad[] =
2319     {
2320         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2321         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2322         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2323         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2324     };
2325     const struct vertex quad2[] =
2326     {
2327         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2328         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2329         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2330         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2331     };
2332
2333     const struct tvertex quad3[] =
2334     {
2335         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2336         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2337         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2338         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2339     };
2340     const struct tvertex quad4[] =
2341     {
2342         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2343         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2344         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2345         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2346     };
2347     HRESULT hr;
2348     DWORD color;
2349     IDirect3DVertexShader9 *shader;
2350     IDirect3DVertexDeclaration9 *decl;
2351     D3DCAPS9 caps;
2352     const DWORD shader_code[] = {
2353         0xfffe0101,                                     /* vs_1_1           */
2354         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2355         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2356         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2357         0x0000ffff                                      /* end              */
2358     };
2359     static const D3DVERTEXELEMENT9 decl_elements[] = {
2360         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2361         D3DDECL_END()
2362     };
2363
2364     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2365
2366     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2367      * then call Present. Then clear the color buffer to make sure it has some defined content
2368      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2369      * by the depth value.
2370      */
2371     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2372     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2373     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2374     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2375     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2376     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2377
2378     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2379     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2380     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2381     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2382     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2383     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2384     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2385     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2386     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2387     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2388
2389     hr = IDirect3DDevice9_BeginScene(device);
2390     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2391     if(hr == D3D_OK)
2392     {
2393         /* Test the untransformed vertex path */
2394         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2395         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2396         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2397         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2398         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2399         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2400
2401         /* Test the transformed vertex path */
2402         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2403         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2404
2405         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2406         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2407         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2408         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2409         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2410         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2411
2412         hr = IDirect3DDevice9_EndScene(device);
2413         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2414     }
2415
2416     /* Do not test the exact corner pixels, but go pretty close to them */
2417
2418     /* Clipped because z > 1.0 */
2419     color = getPixelColor(device, 28, 238);
2420     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2421     color = getPixelColor(device, 28, 241);
2422     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2423     {
2424         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2425     }
2426     else
2427     {
2428         ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2429     }
2430
2431     /* Not clipped, > z buffer clear value(0.75) */
2432     color = getPixelColor(device, 31, 238);
2433     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2434     color = getPixelColor(device, 31, 241);
2435     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2436     color = getPixelColor(device, 100, 238);
2437     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2438     color = getPixelColor(device, 100, 241);
2439     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2440
2441     /* Not clipped, < z buffer clear value */
2442     color = getPixelColor(device, 104, 238);
2443     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2444     color = getPixelColor(device, 104, 241);
2445     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2446     color = getPixelColor(device, 318, 238);
2447     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2448     color = getPixelColor(device, 318, 241);
2449     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2450
2451     /* Clipped because z < 0.0 */
2452     color = getPixelColor(device, 321, 238);
2453     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2454     color = getPixelColor(device, 321, 241);
2455     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2456     {
2457         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2458     }
2459     else
2460     {
2461         ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2462     }
2463
2464     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2465     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2466
2467     /* Test the shader path */
2468     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2469         skip("Vertex shaders not supported\n");
2470         goto out;
2471     }
2472     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2473     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2474     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2475     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2476
2477     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2478
2479     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2480     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2481     IDirect3DDevice9_SetVertexShader(device, shader);
2482     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2483
2484     hr = IDirect3DDevice9_BeginScene(device);
2485     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2486     if(hr == D3D_OK)
2487     {
2488         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2489         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2490         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2491         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2492         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2493         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2494         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2495         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2496         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2497         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2498
2499         hr = IDirect3DDevice9_EndScene(device);
2500         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2501     }
2502
2503     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2504     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2505     IDirect3DDevice9_SetVertexShader(device, NULL);
2506     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2507
2508     IDirect3DVertexDeclaration9_Release(decl);
2509     IDirect3DVertexShader9_Release(shader);
2510
2511     /* Z < 1.0 */
2512     color = getPixelColor(device, 28, 238);
2513     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2514
2515     /* 1.0 < z < 0.75 */
2516     color = getPixelColor(device, 31, 238);
2517     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2518     color = getPixelColor(device, 100, 238);
2519     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2520
2521     /* 0.75 < z < 0.0 */
2522     color = getPixelColor(device, 104, 238);
2523     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2524     color = getPixelColor(device, 318, 238);
2525     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2526
2527     /* 0.0 < z */
2528     color = getPixelColor(device, 321, 238);
2529     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2530
2531     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2532     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2533
2534     out:
2535     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2536     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2537     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2538     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2539     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2540     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2541 }
2542
2543 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2544 {
2545     D3DSURFACE_DESC desc;
2546     D3DLOCKED_RECT l;
2547     HRESULT hr;
2548     unsigned int x, y;
2549     DWORD *mem;
2550
2551     memset(&desc, 0, sizeof(desc));
2552     memset(&l, 0, sizeof(l));
2553     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2554     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2555     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2556     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2557     if(FAILED(hr)) return;
2558
2559     for(y = 0; y < desc.Height; y++)
2560     {
2561         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2562         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2563         {
2564             mem[x] = color;
2565         }
2566     }
2567     hr = IDirect3DSurface9_UnlockRect(surface);
2568     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2569 }
2570
2571 /* This tests a variety of possible StretchRect() situations */
2572 static void stretchrect_test(IDirect3DDevice9 *device)
2573 {
2574     HRESULT hr;
2575     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2576     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2577     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2578     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2579     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2580     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2581     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2582     IDirect3DSurface9 *orig_rt = NULL;
2583     IDirect3DSurface9 *backbuffer = NULL;
2584     DWORD color;
2585
2586     RECT src_rect64 = {0, 0, 64, 64};
2587     RECT src_rect64_flipy = {0, 64, 64, 0};
2588     RECT dst_rect64 = {0, 0, 64, 64};
2589     RECT dst_rect64_flipy = {0, 64, 64, 0};
2590
2591     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2592     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2593     if(!orig_rt) {
2594         goto out;
2595     }
2596
2597     /* Create our temporary surfaces in system memory */
2598     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2599     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2600     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2601     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2602
2603     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2604     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2605     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2606     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2607     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2608     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2609     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2610
2611     /* Create render target surfaces */
2612     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2613     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2614     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2615     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2616     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2617     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2618     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2619     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2620
2621     /* Create render target textures */
2622     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2623     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2624     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2625     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2626     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2627     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2628     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2629     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2630     if (tex_rt32) {
2631         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2632         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2633     }
2634     if (tex_rt64) {
2635         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2636         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2637     }
2638     if (tex_rt_dest64) {
2639         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2640         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2641     }
2642     if (tex_rt_dest64) {
2643         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2644         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2645     }
2646
2647     /* Create regular textures in D3DPOOL_DEFAULT */
2648     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2649     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2650     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2651     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2652     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2653     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2654     if (tex32) {
2655         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2656         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2657     }
2658     if (tex64) {
2659         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2660         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2661     }
2662     if (tex_dest64) {
2663         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2664         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2665     }
2666
2667     /*********************************************************************
2668      * Tests for when the source parameter is an offscreen plain surface *
2669      *********************************************************************/
2670
2671     /* Fill the offscreen 64x64 surface with green */
2672     if (surf_offscreen64)
2673         fill_surface(surf_offscreen64, 0xff00ff00);
2674
2675     /* offscreenplain ==> offscreenplain, same size */
2676     if(surf_offscreen64 && surf_offscreen_dest64) {
2677         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2678         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2679
2680         if (hr == D3D_OK) {
2681             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2682             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2683         }
2684
2685         /* Blit without scaling */
2686         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2687         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2688
2689         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2690         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2691         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2692
2693         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2694         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2695         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2696     }
2697
2698     /* offscreenplain ==> rendertarget texture, same size */
2699     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2700         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2701         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2702
2703         /* We can't lock rendertarget textures, so copy to our temp surface first */
2704         if (hr == D3D_OK) {
2705             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2706             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2707         }
2708
2709         if (hr == D3D_OK) {
2710             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2711             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2712         }
2713
2714         /* Blit without scaling */
2715         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2716         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2717
2718         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2719         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2720         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2721
2722         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2723         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2724         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2725     }
2726
2727     /* offscreenplain ==> rendertarget surface, same size */
2728     if(surf_offscreen64 && surf_rt_dest64) {
2729         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2730         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2731
2732         if (hr == D3D_OK) {
2733             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2734             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2735         }
2736
2737         /* Blit without scaling */
2738         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2739         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2740
2741         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2742         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2743         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2744
2745         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2746         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2747         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2748     }
2749
2750     /* offscreenplain ==> texture, same size (should fail) */
2751     if(surf_offscreen64 && surf_tex_dest64) {
2752         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2753         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2754     }
2755
2756     /* Fill the smaller offscreen surface with red */
2757     fill_surface(surf_offscreen32, 0xffff0000);
2758
2759     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2760     if(surf_offscreen32 && surf_offscreen64) {
2761         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2762         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2763     }
2764
2765     /* offscreenplain ==> rendertarget texture, scaling */
2766     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2767         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2768         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2769
2770         /* We can't lock rendertarget textures, so copy to our temp surface first */
2771         if (hr == D3D_OK) {
2772             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2773             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2774         }
2775
2776         if (hr == D3D_OK) {
2777             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2778             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2779         }
2780     }
2781
2782     /* offscreenplain ==> rendertarget surface, scaling */
2783     if(surf_offscreen32 && surf_rt_dest64) {
2784         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2785         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2786
2787         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2788         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2789     }
2790
2791     /* offscreenplain ==> texture, scaling (should fail) */
2792     if(surf_offscreen32 && surf_tex_dest64) {
2793         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2794         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2795     }
2796
2797     /************************************************************
2798      * Tests for when the source parameter is a regular texture *
2799      ************************************************************/
2800
2801     /* Fill the surface of the regular texture with blue */
2802     if (surf_tex64 && surf_temp64) {
2803         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2804         fill_surface(surf_temp64, 0xff0000ff);
2805         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2806         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2807     }
2808
2809     /* texture ==> offscreenplain, same size */
2810     if(surf_tex64 && surf_offscreen64) {
2811         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2812         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2813     }
2814
2815     /* texture ==> rendertarget texture, same size */
2816     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2817         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2818         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2819
2820         /* We can't lock rendertarget textures, so copy to our temp surface first */
2821         if (hr == D3D_OK) {
2822             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2823             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2824         }
2825
2826         if (hr == D3D_OK) {
2827             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2828             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2829         }
2830
2831         /* Blit without scaling */
2832         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2833         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2834
2835         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2836         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2837         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2838
2839         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2840         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2841         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2842     }
2843
2844     /* texture ==> rendertarget surface, same size */
2845     if(surf_tex64 && surf_rt_dest64) {
2846         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2847         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2848
2849         if (hr == D3D_OK) {
2850             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2851             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2852         }
2853
2854         /* Blit without scaling */
2855         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2856         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2857
2858         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2859         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2860         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2861
2862         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2863         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2864         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2865     }
2866
2867     /* texture ==> texture, same size (should fail) */
2868     if(surf_tex64 && surf_tex_dest64) {
2869         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2870         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2871     }
2872
2873     /* Fill the surface of the smaller regular texture with red */
2874     if (surf_tex32 && surf_temp32) {
2875         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2876         fill_surface(surf_temp32, 0xffff0000);
2877         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2878         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2879     }
2880
2881     /* texture ==> offscreenplain, scaling (should fail) */
2882     if(surf_tex32 && surf_offscreen64) {
2883         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2884         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2885     }
2886
2887     /* texture ==> rendertarget texture, scaling */
2888     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2889         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2890         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2891
2892         /* We can't lock rendertarget textures, so copy to our temp surface first */
2893         if (hr == D3D_OK) {
2894             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2895             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2896         }
2897
2898         if (hr == D3D_OK) {
2899             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2900             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2901         }
2902     }
2903
2904     /* texture ==> rendertarget surface, scaling */
2905     if(surf_tex32 && surf_rt_dest64) {
2906         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2907         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2908
2909         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2910         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2911     }
2912
2913     /* texture ==> texture, scaling (should fail) */
2914     if(surf_tex32 && surf_tex_dest64) {
2915         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2916         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2917     }
2918
2919     /*****************************************************************
2920      * Tests for when the source parameter is a rendertarget texture *
2921      *****************************************************************/
2922
2923     /* Fill the surface of the rendertarget texture with white */
2924     if (surf_tex_rt64 && surf_temp64) {
2925         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2926         fill_surface(surf_temp64, 0xffffffff);
2927         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2928         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2929     }
2930
2931     /* rendertarget texture ==> offscreenplain, same size */
2932     if(surf_tex_rt64 && surf_offscreen64) {
2933         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2934         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2935     }
2936
2937     /* rendertarget texture ==> rendertarget texture, same size */
2938     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2939         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2940         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2941
2942         /* We can't lock rendertarget textures, so copy to our temp surface first */
2943         if (hr == D3D_OK) {
2944             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2945             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2946         }
2947
2948         if (hr == D3D_OK) {
2949             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2950             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2951         }
2952
2953         /* Blit without scaling */
2954         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2955         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2956
2957         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2958         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2959         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2960
2961         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2962         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2963         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2964     }
2965
2966     /* rendertarget texture ==> rendertarget surface, same size */
2967     if(surf_tex_rt64 && surf_rt_dest64) {
2968         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2969         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2970
2971         if (hr == D3D_OK) {
2972             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2973             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2974         }
2975
2976         /* Blit without scaling */
2977         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2978         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2979
2980         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2981         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2982         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2983
2984         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2985         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2986         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2987     }
2988
2989     /* rendertarget texture ==> texture, same size (should fail) */
2990     if(surf_tex_rt64 && surf_tex_dest64) {
2991         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2992         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2993     }
2994
2995     /* Fill the surface of the smaller rendertarget texture with red */
2996     if (surf_tex_rt32 && surf_temp32) {
2997         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2998         fill_surface(surf_temp32, 0xffff0000);
2999         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3000         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3001     }
3002
3003     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
3004     if(surf_tex_rt32 && surf_offscreen64) {
3005         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
3006         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3007     }
3008
3009     /* rendertarget texture ==> rendertarget texture, scaling */
3010     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3011         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3012         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3013
3014         /* We can't lock rendertarget textures, so copy to our temp surface first */
3015         if (hr == D3D_OK) {
3016             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3017             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3018         }
3019
3020         if (hr == D3D_OK) {
3021             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3022             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3023         }
3024     }
3025
3026     /* rendertarget texture ==> rendertarget surface, scaling */
3027     if(surf_tex_rt32 && surf_rt_dest64) {
3028         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
3029         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3030
3031         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3032         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3033     }
3034
3035     /* rendertarget texture ==> texture, scaling (should fail) */
3036     if(surf_tex_rt32 && surf_tex_dest64) {
3037         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
3038         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3039     }
3040
3041     /*****************************************************************
3042      * Tests for when the source parameter is a rendertarget surface *
3043      *****************************************************************/
3044
3045     /* Fill the surface of the rendertarget surface with black */
3046     if (surf_rt64)
3047         fill_surface(surf_rt64, 0xff000000);
3048
3049     /* rendertarget texture ==> offscreenplain, same size */
3050     if(surf_rt64 && surf_offscreen64) {
3051         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
3052         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3053     }
3054
3055     /* rendertarget surface ==> rendertarget texture, same size */
3056     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3057         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3058         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3059
3060         /* We can't lock rendertarget textures, so copy to our temp surface first */
3061         if (hr == D3D_OK) {
3062             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3063             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3064         }
3065
3066         if (hr == D3D_OK) {
3067             color = getPixelColorFromSurface(surf_temp64, 32, 32);
3068             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3069         }
3070
3071         /* Blit without scaling */
3072         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3073         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3074
3075         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3076         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3077         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3078
3079         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3080         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3081         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3082     }
3083
3084     /* rendertarget surface ==> rendertarget surface, same size */
3085     if(surf_rt64 && surf_rt_dest64) {
3086         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
3087         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3088
3089         if (hr == D3D_OK) {
3090             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3091             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3092         }
3093
3094         /* Blit without scaling */
3095         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3096         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3097
3098         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3099         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
3100         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3101
3102         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3103         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3104         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3105     }
3106
3107     /* rendertarget surface ==> texture, same size (should fail) */
3108     if(surf_rt64 && surf_tex_dest64) {
3109         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
3110         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3111     }
3112
3113     /* Fill the surface of the smaller rendertarget texture with red */
3114     if (surf_rt32)
3115         fill_surface(surf_rt32, 0xffff0000);
3116
3117     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
3118     if(surf_rt32 && surf_offscreen64) {
3119         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
3120         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3121     }
3122
3123     /* rendertarget surface ==> rendertarget texture, scaling */
3124     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3125         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3126         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3127
3128         /* We can't lock rendertarget textures, so copy to our temp surface first */
3129         if (hr == D3D_OK) {
3130             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3131             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3132         }
3133
3134         if (hr == D3D_OK) {
3135             color = getPixelColorFromSurface(surf_temp64, 48, 48);
3136             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3137         }
3138     }
3139
3140     /* rendertarget surface ==> rendertarget surface, scaling */
3141     if(surf_rt32 && surf_rt_dest64) {
3142         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
3143         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3144
3145         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3146         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3147     }
3148
3149     /* rendertarget surface ==> texture, scaling (should fail) */
3150     if(surf_rt32 && surf_tex_dest64) {
3151         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
3152         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3153     }
3154
3155     /* backbuffer ==> surface tests (no scaling) */
3156     if(backbuffer && surf_tex_rt_dest640_480)
3157     {
3158         RECT src_rect = {0, 0, 640, 480};
3159         RECT src_rect_flipy = {0, 480, 640, 0};
3160         RECT dst_rect = {0, 0, 640, 480};
3161         RECT dst_rect_flipy = {0, 480, 640, 0};
3162
3163         /* Blit with NULL rectangles */
3164         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
3165         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
3166
3167         /* Blit without scaling */
3168         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
3169         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3170
3171         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3172         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
3173         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3174
3175         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3176         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
3177         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3178     }
3179
3180     /* TODO: Test format conversions */
3181
3182
3183 out:
3184     /* Clean up */
3185     if (backbuffer)
3186         IDirect3DSurface9_Release(backbuffer);
3187     if (surf_rt32)
3188         IDirect3DSurface9_Release(surf_rt32);
3189     if (surf_rt64)
3190         IDirect3DSurface9_Release(surf_rt64);
3191     if (surf_rt_dest64)
3192         IDirect3DSurface9_Release(surf_rt_dest64);
3193     if (surf_temp32)
3194         IDirect3DSurface9_Release(surf_temp32);
3195     if (surf_temp64)
3196         IDirect3DSurface9_Release(surf_temp64);
3197     if (surf_offscreen32)
3198         IDirect3DSurface9_Release(surf_offscreen32);
3199     if (surf_offscreen64)
3200         IDirect3DSurface9_Release(surf_offscreen64);
3201     if (surf_offscreen_dest64)
3202         IDirect3DSurface9_Release(surf_offscreen_dest64);
3203
3204     if (tex_rt32) {
3205         if (surf_tex_rt32)
3206             IDirect3DSurface9_Release(surf_tex_rt32);
3207         IDirect3DTexture9_Release(tex_rt32);
3208     }
3209     if (tex_rt64) {
3210         if (surf_tex_rt64)
3211             IDirect3DSurface9_Release(surf_tex_rt64);
3212         IDirect3DTexture9_Release(tex_rt64);
3213     }
3214     if (tex_rt_dest64) {
3215         if (surf_tex_rt_dest64)
3216             IDirect3DSurface9_Release(surf_tex_rt_dest64);
3217         IDirect3DTexture9_Release(tex_rt_dest64);
3218     }
3219     if (tex_rt_dest640_480) {
3220         if (surf_tex_rt_dest640_480)
3221             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
3222         IDirect3DTexture9_Release(tex_rt_dest640_480);
3223     }
3224     if (tex32) {
3225         if (surf_tex32)
3226             IDirect3DSurface9_Release(surf_tex32);
3227         IDirect3DTexture9_Release(tex32);
3228     }
3229     if (tex64) {
3230         if (surf_tex64)
3231             IDirect3DSurface9_Release(surf_tex64);
3232         IDirect3DTexture9_Release(tex64);
3233     }
3234     if (tex_dest64) {
3235         if (surf_tex_dest64)
3236             IDirect3DSurface9_Release(surf_tex_dest64);
3237         IDirect3DTexture9_Release(tex_dest64);
3238     }
3239
3240     if (orig_rt) {
3241         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3242         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3243         IDirect3DSurface9_Release(orig_rt);
3244     }
3245 }
3246
3247 static void maxmip_test(IDirect3DDevice9 *device)
3248 {
3249     IDirect3DTexture9 *texture = NULL;
3250     IDirect3DSurface9 *surface = NULL;
3251     HRESULT hr;
3252     DWORD color;
3253     static const struct
3254     {
3255         struct
3256         {
3257             float x, y, z;
3258             float s, t;
3259         }
3260         v[4];
3261     }
3262     quads[] =
3263     {
3264         {{
3265             {-1.0, -1.0,  0.0,  0.0,  0.0},
3266             {-1.0,  0.0,  0.0,  0.0,  1.0},
3267             { 0.0, -1.0,  0.0,  1.0,  0.0},
3268             { 0.0,  0.0,  0.0,  1.0,  1.0},
3269         }},
3270         {{
3271             { 0.0, -1.0,  0.0,  0.0,  0.0},
3272             { 0.0,  0.0,  0.0,  0.0,  1.0},
3273             { 1.0, -1.0,  0.0,  1.0,  0.0},
3274             { 1.0,  0.0,  0.0,  1.0,  1.0},
3275         }},
3276         {{
3277             { 0.0,  0.0,  0.0,  0.0,  0.0},
3278             { 0.0,  1.0,  0.0,  0.0,  1.0},
3279             { 1.0,  0.0,  0.0,  1.0,  0.0},
3280             { 1.0,  1.0,  0.0,  1.0,  1.0},
3281         }},
3282         {{
3283             {-1.0,  0.0,  0.0,  0.0,  0.0},
3284             {-1.0,  1.0,  0.0,  0.0,  1.0},
3285             { 0.0,  0.0,  0.0,  1.0,  0.0},
3286             { 0.0,  1.0,  0.0,  1.0,  1.0},
3287         }},
3288     };
3289
3290     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3291                                         &texture, NULL);
3292     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3293     if(!texture)
3294     {
3295         skip("Failed to create test texture\n");
3296         return;
3297     }
3298
3299     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3300     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3301     fill_surface(surface, 0xffff0000);
3302     IDirect3DSurface9_Release(surface);
3303     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3304     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3305     fill_surface(surface, 0xff00ff00);
3306     IDirect3DSurface9_Release(surface);
3307     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3308     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3309     fill_surface(surface, 0xff0000ff);
3310     IDirect3DSurface9_Release(surface);
3311
3312     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3313     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3314     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3315     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3316
3317     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3318     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3319
3320     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3321     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3322
3323     hr = IDirect3DDevice9_BeginScene(device);
3324     if(SUCCEEDED(hr))
3325     {
3326         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3327         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3328         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3329         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3330
3331         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3332         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3333         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3334         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3335
3336         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3337         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3338         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3339         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3340
3341         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3342         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3343         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3344         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3345         hr = IDirect3DDevice9_EndScene(device);
3346         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3347     }
3348
3349     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3350     color = getPixelColor(device, 160, 360);
3351     ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3352     color = getPixelColor(device, 480, 360);
3353     ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3354     color = getPixelColor(device, 480, 120);
3355     ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3356     color = getPixelColor(device, 160, 120);
3357     ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3358     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3359     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3360
3361     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3362     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3363
3364     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3365     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3366
3367     hr = IDirect3DDevice9_BeginScene(device);
3368     if(SUCCEEDED(hr))
3369     {
3370         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3371         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3372         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3373         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3374
3375         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3376         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3377         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3378         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3379
3380         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3381         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3382         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3383         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3384
3385         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3386         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3387         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3388         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3389         hr = IDirect3DDevice9_EndScene(device);
3390         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3391     }
3392
3393     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3394      * level 3 (> levels in texture) samples from the highest level in the
3395      * texture (level 2). */
3396     color = getPixelColor(device, 160, 360);
3397     ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3398     color = getPixelColor(device, 480, 360);
3399     ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3400     color = getPixelColor(device, 480, 120);
3401     ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3402     color = getPixelColor(device, 160, 120);
3403     ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3404     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3405     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3406
3407     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3408     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3409
3410     hr = IDirect3DDevice9_BeginScene(device);
3411     if(SUCCEEDED(hr))
3412     {
3413         DWORD ret;
3414
3415         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3416         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3417         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3418         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3419         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3420         ret = IDirect3DTexture9_SetLOD(texture, 1);
3421         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3422         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3423         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3424
3425         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3426         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3427         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3428         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3429         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3430         ret = IDirect3DTexture9_SetLOD(texture, 2);
3431         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3432         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3433         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3434
3435         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3436         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3437         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3438         ret = IDirect3DTexture9_SetLOD(texture, 1);
3439         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3440         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3441         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3442
3443         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3444         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3445         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3446         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3447         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3448         ret = IDirect3DTexture9_SetLOD(texture, 1);
3449         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3450         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3451         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3452         hr = IDirect3DDevice9_EndScene(device);
3453         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3454     }
3455
3456     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3457      * level 3 (> levels in texture) samples from the highest level in the
3458      * texture (level 2). */
3459     color = getPixelColor(device, 160, 360);
3460     ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3461     color = getPixelColor(device, 480, 360);
3462     ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3463     color = getPixelColor(device, 480, 120);
3464     ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3465     color = getPixelColor(device, 160, 120);
3466     ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3467
3468     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3469     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3470
3471     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3472     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3473     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3474     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3475     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3476     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3477     IDirect3DTexture9_Release(texture);
3478 }
3479
3480 static void release_buffer_test(IDirect3DDevice9 *device)
3481 {
3482     IDirect3DVertexBuffer9 *vb = NULL;
3483     IDirect3DIndexBuffer9 *ib = NULL;
3484     HRESULT hr;
3485     BYTE *data;
3486     LONG ref;
3487
3488     static const struct vertex quad[] = {
3489         {-1.0,      -1.0,       0.1,        0xffff0000},
3490         {-1.0,       1.0,       0.1,        0xffff0000},
3491         { 1.0,       1.0,       0.1,        0xffff0000},
3492
3493         {-1.0,      -1.0,       0.1,        0xff00ff00},
3494         {-1.0,       1.0,       0.1,        0xff00ff00},
3495         { 1.0,       1.0,       0.1,        0xff00ff00}
3496     };
3497     short indices[] = {3, 4, 5};
3498
3499     /* Index and vertex buffers should always be creatable */
3500     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3501                                               D3DPOOL_MANAGED, &vb, NULL);
3502     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3503     if(!vb) {
3504         skip("Failed to create a vertex buffer\n");
3505         return;
3506     }
3507     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3508     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3509     if(!ib) {
3510         skip("Failed to create an index buffer\n");
3511         return;
3512     }
3513
3514     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3515     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3516     memcpy(data, quad, sizeof(quad));
3517     hr = IDirect3DVertexBuffer9_Unlock(vb);
3518     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3519
3520     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3521     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3522     memcpy(data, indices, sizeof(indices));
3523     hr = IDirect3DIndexBuffer9_Unlock(ib);
3524     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3525
3526     hr = IDirect3DDevice9_SetIndices(device, ib);
3527     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3528     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3529     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3530     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3531     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3532
3533     /* Now destroy the bound index buffer and draw again */
3534     ref = IDirect3DIndexBuffer9_Release(ib);
3535     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3536
3537     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3538     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3539
3540     hr = IDirect3DDevice9_BeginScene(device);
3541     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3542     if(SUCCEEDED(hr))
3543     {
3544         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3545          * making assumptions about the indices or vertices
3546          */
3547         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3548         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3549         hr = IDirect3DDevice9_EndScene(device);
3550         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3551     }
3552
3553     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3554     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3555
3556     hr = IDirect3DDevice9_SetIndices(device, NULL);
3557     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3558     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3559     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3560
3561     /* Index buffer was already destroyed as part of the test */
3562     IDirect3DVertexBuffer9_Release(vb);
3563 }
3564
3565 static void float_texture_test(IDirect3DDevice9 *device)
3566 {
3567     IDirect3D9 *d3d = NULL;
3568     HRESULT hr;
3569     IDirect3DTexture9 *texture = NULL;
3570     D3DLOCKED_RECT lr;
3571     float *data;
3572     DWORD color;
3573     float quad[] = {
3574         -1.0,      -1.0,       0.1,     0.0,    0.0,
3575         -1.0,       1.0,       0.1,     0.0,    1.0,
3576          1.0,      -1.0,       0.1,     1.0,    0.0,
3577          1.0,       1.0,       0.1,     1.0,    1.0,
3578     };
3579
3580     memset(&lr, 0, sizeof(lr));
3581     IDirect3DDevice9_GetDirect3D(device, &d3d);
3582     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3583                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3584         skip("D3DFMT_R32F textures not supported\n");
3585         goto out;
3586     }
3587
3588     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3589                                         D3DPOOL_MANAGED, &texture, NULL);
3590     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3591     if(!texture) {
3592         skip("Failed to create R32F texture\n");
3593         goto out;
3594     }
3595
3596     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3597     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3598     data = lr.pBits;
3599     *data = 0.0;
3600     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3601     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3602
3603     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3604     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3605
3606     hr = IDirect3DDevice9_BeginScene(device);
3607     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3608     if(SUCCEEDED(hr))
3609     {
3610         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3611         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3612
3613         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3614         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3615
3616         hr = IDirect3DDevice9_EndScene(device);
3617         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3618     }
3619     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3620     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3621
3622     color = getPixelColor(device, 240, 320);
3623     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3624
3625     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3626     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3627
3628 out:
3629     if(texture) IDirect3DTexture9_Release(texture);
3630     IDirect3D9_Release(d3d);
3631 }
3632
3633 static void g16r16_texture_test(IDirect3DDevice9 *device)
3634 {
3635     IDirect3D9 *d3d = NULL;
3636     HRESULT hr;
3637     IDirect3DTexture9 *texture = NULL;
3638     D3DLOCKED_RECT lr;
3639     DWORD *data;
3640     DWORD color;
3641     float quad[] = {
3642        -1.0,      -1.0,       0.1,     0.0,    0.0,
3643        -1.0,       1.0,       0.1,     0.0,    1.0,
3644         1.0,      -1.0,       0.1,     1.0,    0.0,
3645         1.0,       1.0,       0.1,     1.0,    1.0,
3646     };
3647
3648     memset(&lr, 0, sizeof(lr));
3649     IDirect3DDevice9_GetDirect3D(device, &d3d);
3650     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3651        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3652            skip("D3DFMT_G16R16 textures not supported\n");
3653            goto out;
3654     }
3655
3656     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3657                                         D3DPOOL_MANAGED, &texture, NULL);
3658     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3659     if(!texture) {
3660         skip("Failed to create D3DFMT_G16R16 texture\n");
3661         goto out;
3662     }
3663
3664     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3665     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3666     data = lr.pBits;
3667     *data = 0x0f00f000;
3668     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3669     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3670
3671     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3672     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3673
3674     hr = IDirect3DDevice9_BeginScene(device);
3675     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3676     if(SUCCEEDED(hr))
3677     {
3678         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3679         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3680
3681         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3682         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3683
3684         hr = IDirect3DDevice9_EndScene(device);
3685         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3686     }
3687     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3688     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3689
3690     color = getPixelColor(device, 240, 320);
3691     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3692        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3693
3694     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3695     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3696
3697 out:
3698     if(texture) IDirect3DTexture9_Release(texture);
3699     IDirect3D9_Release(d3d);
3700 }
3701
3702 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
3703 {
3704     LONG x_coords[2][2] =
3705     {
3706         {r.left - 1, r.left + 1},
3707         {r.right + 1, r.right - 1},
3708     };
3709     LONG y_coords[2][2] =
3710     {
3711         {r.top - 1, r.top + 1},
3712         {r.bottom + 1, r.bottom - 1}
3713     };
3714     unsigned int i, j, x_side, y_side;
3715
3716     for (i = 0; i < 2; ++i)
3717     {
3718         for (j = 0; j < 2; ++j)
3719         {
3720             for (x_side = 0; x_side < 2; ++x_side)
3721             {
3722                 for (y_side = 0; y_side < 2; ++y_side)
3723                 {
3724                     unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
3725                     DWORD color;
3726                     DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
3727
3728                     color = getPixelColor(device, x, y);
3729                     ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
3730                             message, x, y, color, expected);
3731                 }
3732             }
3733         }
3734     }
3735 }
3736
3737 struct projected_textures_test_run
3738 {
3739     const char *message;
3740     DWORD flags;
3741     IDirect3DVertexDeclaration9 *decl;
3742     BOOL vs, ps;
3743     RECT rect;
3744 };
3745
3746 static void projected_textures_test(IDirect3DDevice9 *device,
3747         struct projected_textures_test_run tests[4])
3748 {
3749     unsigned int i;
3750
3751     static const DWORD vertex_shader[] =
3752     {
3753         0xfffe0101,                                     /* vs_1_1           */
3754         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
3755         0x0000001f, 0x80000005, 0x900f0001,             /* dcl_texcoord0 v1 */
3756         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
3757         0x00000001, 0xe00f0000, 0x90e40001,             /* mov oT0, v1      */
3758         0x0000ffff                                      /* end              */
3759     };
3760     static const DWORD pixel_shader[] =
3761     {
3762         0xffff0103,                                     /* ps_1_3           */
3763         0x00000042, 0xb00f0000,                         /* tex t0           */
3764         0x00000001, 0x800f0000, 0xb0e40000,             /* mov r0, t0       */
3765         0x0000ffff                                      /* end              */
3766     };
3767     IDirect3DVertexShader9 *vs = NULL;
3768     IDirect3DPixelShader9 *ps = NULL;
3769     HRESULT hr;
3770
3771     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
3772     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
3773     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
3774     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3775
3776     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
3777     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3778
3779     hr = IDirect3DDevice9_BeginScene(device);
3780     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3781     if (FAILED(hr))
3782         return;
3783
3784     for (i = 0; i < 4; ++i)
3785     {
3786         DWORD value = 0xdeadbeef;
3787         static const float proj_quads[] =
3788         {
3789             -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3790              0.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3791             -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3792              0.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3793
3794              0.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3795              1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3796              0.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3797              1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3798
3799             -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3800              0.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3801             -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3802              0.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3803
3804              0.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3805              1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3806              0.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3807              1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3808         };
3809
3810         if (tests[i].vs)
3811             hr = IDirect3DDevice9_SetVertexShader(device, vs);
3812         else
3813             hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3814         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
3815         if (tests[i].ps)
3816             hr = IDirect3DDevice9_SetPixelShader(device, ps);
3817         else
3818             hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3819         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3820
3821         hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
3822         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3823
3824         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
3825         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3826         hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
3827         ok(SUCCEEDED(hr) && value == tests[i].flags,
3828                 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
3829
3830         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
3831                 &proj_quads[i * 4 * 7], 7 * sizeof(float));
3832         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3833     }
3834
3835     hr = IDirect3DDevice9_EndScene(device);
3836     ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3837
3838     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3839     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3840     IDirect3DVertexShader9_Release(vs);
3841     IDirect3DPixelShader9_Release(ps);
3842
3843     for (i = 0; i < 4; ++i)
3844         check_rect(device, tests[i].rect, tests[i].message);
3845
3846     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3847     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3848 }
3849
3850 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3851 {
3852     HRESULT hr;
3853     IDirect3D9 *d3d;
3854     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3855     D3DCAPS9 caps;
3856     IDirect3DTexture9 *texture = NULL;
3857     IDirect3DVolumeTexture9 *volume = NULL;
3858     unsigned int x, y, z;
3859     D3DLOCKED_RECT lr;
3860     D3DLOCKED_BOX lb;
3861     DWORD color;
3862     UINT w, h;
3863     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
3864     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3865                            0.0, 1.0, 0.0, 0.0,
3866                            0.0, 0.0, 1.0, 0.0,
3867                            0.0, 0.0, 0.0, 1.0};
3868     static const D3DVERTEXELEMENT9 decl_elements[] = {
3869         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3870         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3871         D3DDECL_END()
3872     };
3873     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3874         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3875         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3876         D3DDECL_END()
3877     };
3878     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3879         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3880         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3881         D3DDECL_END()
3882     };
3883     static const D3DVERTEXELEMENT9 decl_elements4[] = {
3884         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3885         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3886         D3DDECL_END()
3887     };
3888     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3889                                                  0x00, 0xff, 0x00, 0x00,
3890                                                  0x00, 0x00, 0x00, 0x00,
3891                                                  0x00, 0x00, 0x00, 0x00};
3892
3893     memset(&lr, 0, sizeof(lr));
3894     memset(&lb, 0, sizeof(lb));
3895     IDirect3DDevice9_GetDirect3D(device, &d3d);
3896     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3897                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3898         fmt = D3DFMT_A16B16G16R16;
3899     }
3900     IDirect3D9_Release(d3d);
3901
3902     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3903     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3904     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3905     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3906     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3907     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3908     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
3909     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3910     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3911     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3912     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3913     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3914     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3915     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3916     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3917     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3918     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3919     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3920     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3921     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3922     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3923     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3924     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3925     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3926     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3927     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3928
3929     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3930     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3931     w = min(1024, caps.MaxTextureWidth);
3932     h = min(1024, caps.MaxTextureHeight);
3933     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3934                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3935     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3936     if(!texture) {
3937         skip("Failed to create the test texture\n");
3938         return;
3939     }
3940
3941     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3942      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3943      * 1.0 in red and green for the x and y coords
3944      */
3945     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3946     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3947     for(y = 0; y < h; y++) {
3948         for(x = 0; x < w; x++) {
3949             double r_f = (double) y / (double) h;
3950             double g_f = (double) x / (double) w;
3951             if(fmt == D3DFMT_A16B16G16R16) {
3952                 unsigned short r, g;
3953                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3954                 r = (unsigned short) (r_f * 65536.0);
3955                 g = (unsigned short) (g_f * 65536.0);
3956                 dst[0] = r;
3957                 dst[1] = g;
3958                 dst[2] = 0;
3959                 dst[3] = 65535;
3960             } else {
3961                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3962                 unsigned char r = (unsigned char) (r_f * 255.0);
3963                 unsigned char g = (unsigned char) (g_f * 255.0);
3964                 dst[0] = 0;
3965                 dst[1] = g;
3966                 dst[2] = r;
3967                 dst[3] = 255;
3968             }
3969         }
3970     }
3971     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3972     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3973     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3974     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3975
3976     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3977     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3978     hr = IDirect3DDevice9_BeginScene(device);
3979     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3980     if(SUCCEEDED(hr))
3981     {
3982         float quad1[] = {
3983             -1.0,      -1.0,       0.1,     1.0,    1.0,
3984             -1.0,       0.0,       0.1,     1.0,    1.0,
3985              0.0,      -1.0,       0.1,     1.0,    1.0,
3986              0.0,       0.0,       0.1,     1.0,    1.0,
3987         };
3988         float quad2[] = {
3989             -1.0,       0.0,       0.1,     1.0,    1.0,
3990             -1.0,       1.0,       0.1,     1.0,    1.0,
3991              0.0,       0.0,       0.1,     1.0,    1.0,
3992              0.0,       1.0,       0.1,     1.0,    1.0,
3993         };
3994         float quad3[] = {
3995              0.0,       0.0,       0.1,     0.5,    0.5,
3996              0.0,       1.0,       0.1,     0.5,    0.5,
3997              1.0,       0.0,       0.1,     0.5,    0.5,
3998              1.0,       1.0,       0.1,     0.5,    0.5,
3999         };
4000         float quad4[] = {
4001              320,       480,       0.1,     1.0,    0.0,    1.0,
4002              320,       240,       0.1,     1.0,    0.0,    1.0,
4003              640,       480,       0.1,     1.0,    0.0,    1.0,
4004              640,       240,       0.1,     1.0,    0.0,    1.0,
4005         };
4006         float mat[16] = {0.0, 0.0, 0.0, 0.0,
4007                           0.0, 0.0, 0.0, 0.0,
4008                           0.0, 0.0, 0.0, 0.0,
4009                           0.0, 0.0, 0.0, 0.0};
4010
4011         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4012         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4013         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4014         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4015         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4016
4017         /* What happens with transforms enabled? */
4018         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4019         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4020         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4021         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4022
4023         /* What happens if 4 coords are used, but only 2 given ?*/
4024         mat[8] = 1.0;
4025         mat[13] = 1.0;
4026         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4027         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4028         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4029         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4030         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4031         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4032
4033         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4034          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4035          * due to the coords in the vertices. (turns out red, indeed)
4036          */
4037         memset(mat, 0, sizeof(mat));
4038         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4039         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4040         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4041         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4042         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4043         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4044         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4045         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4046
4047         hr = IDirect3DDevice9_EndScene(device);
4048         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4049     }
4050     color = getPixelColor(device, 160, 360);
4051     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
4052     color = getPixelColor(device, 160, 120);
4053     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4054     color = getPixelColor(device, 480, 120);
4055     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
4056     color = getPixelColor(device, 480, 360);
4057     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
4058     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4059     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4060
4061     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4062     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4063
4064     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4065     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4066     hr = IDirect3DDevice9_BeginScene(device);
4067     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4068     if(SUCCEEDED(hr))
4069     {
4070         float quad1[] = {
4071             -1.0,      -1.0,       0.1,     0.8,    0.2,
4072             -1.0,       0.0,       0.1,     0.8,    0.2,
4073              0.0,      -1.0,       0.1,     0.8,    0.2,
4074              0.0,       0.0,       0.1,     0.8,    0.2,
4075         };
4076         float quad2[] = {
4077             -1.0,       0.0,       0.1,     0.5,    1.0,
4078             -1.0,       1.0,       0.1,     0.5,    1.0,
4079              0.0,       0.0,       0.1,     0.5,    1.0,
4080              0.0,       1.0,       0.1,     0.5,    1.0,
4081         };
4082         float quad3[] = {
4083              0.0,       0.0,       0.1,     0.5,    1.0,
4084              0.0,       1.0,       0.1,     0.5,    1.0,
4085              1.0,       0.0,       0.1,     0.5,    1.0,
4086              1.0,       1.0,       0.1,     0.5,    1.0,
4087         };
4088         float quad4[] = {
4089              0.0,      -1.0,       0.1,     0.8,    0.2,
4090              0.0,       0.0,       0.1,     0.8,    0.2,
4091              1.0,      -1.0,       0.1,     0.8,    0.2,
4092              1.0,       0.0,       0.1,     0.8,    0.2,
4093         };
4094         float mat[16] = {0.0, 0.0, 0.0, 0.0,
4095                           0.0, 0.0, 0.0, 0.0,
4096                           0.0, 1.0, 0.0, 0.0,
4097                           0.0, 0.0, 0.0, 0.0};
4098
4099         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
4100          */
4101         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4102         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4103         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4104         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4105
4106         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4107         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4108
4109         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
4110          * it behaves like COUNT2 because normal textures require 2 coords
4111          */
4112         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4113         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4114         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
4115         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4116
4117         /* Just to be sure, the same as quad2 above */
4118         memset(mat, 0, sizeof(mat));
4119         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4120         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4121         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4122         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4123         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4124         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4125
4126         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
4127          * used? And what happens to the first?
4128          */
4129         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4130         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4131         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4132         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4133
4134         hr = IDirect3DDevice9_EndScene(device);
4135         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4136     }
4137     color = getPixelColor(device, 160, 360);
4138     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
4139     color = getPixelColor(device, 160, 120);
4140     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4141     color = getPixelColor(device, 480, 120);
4142     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
4143        "quad 3 has color %08x, expected 0x00ff8000\n", color);
4144     color = getPixelColor(device, 480, 360);
4145     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
4146        "quad 4 has color %08x, expected 0x0033cc00\n", color);
4147     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4148     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4149
4150     IDirect3DTexture9_Release(texture);
4151
4152     /* Test projected textures, without any fancy matrices */
4153     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
4154     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4155     if (SUCCEEDED(hr))
4156     {
4157         struct projected_textures_test_run projected_tests_1[4] =
4158         {
4159             {
4160                 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
4161                 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
4162                 decl3,
4163                 FALSE, TRUE,
4164                 {120, 300, 240, 390},
4165             },
4166             {
4167                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
4168                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4169                 decl3,
4170                 FALSE, TRUE,
4171                 {400, 360, 480, 420},
4172             },
4173             /* Try with some invalid values */
4174             {
4175                 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
4176                 0xffffffff,
4177                 decl3,
4178                 FALSE, TRUE,
4179                 {120, 60, 240, 150}
4180             },
4181             {
4182                 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
4183                 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4184                 decl4,
4185                 FALSE, TRUE,
4186                 {340, 210, 360, 225},
4187             }
4188         };
4189         struct projected_textures_test_run projected_tests_2[4] =
4190         {
4191             {
4192                 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
4193                 D3DTTFF_PROJECTED,
4194                 decl3,
4195                 FALSE, TRUE,
4196                 {120, 300, 240, 390},
4197             },
4198             {
4199                 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
4200                 D3DTTFF_PROJECTED,
4201                 decl,
4202                 FALSE, TRUE,
4203                 {400, 360, 480, 420},
4204             },
4205             {
4206                 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
4207                 0xffffffff,
4208                 decl,
4209                 FALSE, TRUE,
4210                 {80, 120, 160, 180},
4211             },
4212             {
4213                 "D3DTTFF_COUNT1 (draws non-projected) - top right",
4214                 D3DTTFF_COUNT1,
4215                 decl4,
4216                 FALSE, TRUE,
4217                 {340, 210, 360, 225},
4218             }
4219         };
4220         struct projected_textures_test_run projected_tests_3[4] =
4221         {
4222             {
4223                 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
4224                 D3DTTFF_PROJECTED,
4225                 decl3,
4226                 TRUE, TRUE,
4227                 {120, 300, 240, 390},
4228             },
4229             {
4230                 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, the w component has the default value 1.0) - bottom right",
4231                 D3DTTFF_PROJECTED,
4232                 decl,
4233                 TRUE, TRUE,
4234                 {340, 450, 360, 465},
4235             },
4236             {
4237                 "0xffffffff (like COUNT4 | PROJECTED, the w component has the default value 1.0) - top left",
4238                 0xffffffff,
4239                 decl,
4240                 TRUE, TRUE,
4241                 {20, 210, 40, 225},
4242             },
4243             {
4244                 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
4245                 D3DTTFF_PROJECTED,
4246                 decl3,
4247                 FALSE, FALSE,
4248                 {440, 60, 560, 150},
4249             },
4250         };
4251
4252         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4253         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4254
4255         hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4256         ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4257         for(x = 0; x < 4; x++) {
4258             memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
4259         }
4260         hr = IDirect3DTexture9_UnlockRect(texture, 0);
4261         ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4262         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4263         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4264
4265         projected_textures_test(device, projected_tests_1);
4266         projected_textures_test(device, projected_tests_2);
4267         projected_textures_test(device, projected_tests_3);
4268
4269         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4270         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4271         IDirect3DTexture9_Release(texture);
4272     }
4273
4274     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
4275     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4276     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
4277      * Thus watch out if sampling from texels between 0 and 1.
4278      */
4279     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
4280     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
4281        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
4282     if(!volume) {
4283         skip("Failed to create a volume texture\n");
4284         goto out;
4285     }
4286
4287     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
4288     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
4289     for(z = 0; z < 32; z++) {
4290         for(y = 0; y < 32; y++) {
4291             for(x = 0; x < 32; x++) {
4292                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
4293                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
4294                 float r_f = (float) x / 31.0;
4295                 float g_f = (float) y / 31.0;
4296                 float b_f = (float) z / 31.0;
4297
4298                 if(fmt == D3DFMT_A16B16G16R16) {
4299                     unsigned short *mem_s = mem;
4300                     mem_s[0]  = r_f * 65535.0;
4301                     mem_s[1]  = g_f * 65535.0;
4302                     mem_s[2]  = b_f * 65535.0;
4303                     mem_s[3]  = 65535;
4304                 } else {
4305                     unsigned char *mem_c = mem;
4306                     mem_c[0]  = b_f * 255.0;
4307                     mem_c[1]  = g_f * 255.0;
4308                     mem_c[2]  = r_f * 255.0;
4309                     mem_c[3]  = 255;
4310                 }
4311             }
4312         }
4313     }
4314     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
4315     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4316
4317     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
4318     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4319
4320     hr = IDirect3DDevice9_BeginScene(device);
4321     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4322     if(SUCCEEDED(hr))
4323     {
4324         float quad1[] = {
4325             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4326             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4327              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4328              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4329         };
4330         float quad2[] = {
4331             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4332             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
4333              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4334              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
4335         };
4336         float quad3[] = {
4337              0.0,       0.0,       0.1,     0.0,    0.0,
4338              0.0,       1.0,       0.1,     0.0,    0.0,
4339              1.0,       0.0,       0.1,     0.0,    0.0,
4340              1.0,       1.0,       0.1,     0.0,    0.0
4341         };
4342         float quad4[] = {
4343              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4344              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4345              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4346              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
4347         };
4348         float mat[16] = {1.0, 0.0, 0.0, 0.0,
4349                          0.0, 0.0, 1.0, 0.0,
4350                          0.0, 1.0, 0.0, 0.0,
4351                          0.0, 0.0, 0.0, 1.0};
4352         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4353         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4354
4355         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
4356          * values
4357          */
4358         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4359         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4360         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4361         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4362         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4363         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4364
4365         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
4366          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
4367          * otherwise the w will be missing(blue).
4368          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
4369          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
4370          */
4371         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4372         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4373         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4374         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4375
4376         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
4377         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4378         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4379         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4380         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4381         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4382         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4383         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4384         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4385
4386         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4387          * disable. ATI extends it up to the amount of values needed for the volume texture
4388          */
4389         memset(mat, 0, sizeof(mat));
4390         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4391         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4392         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4393         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4394         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4395         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4396         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4397         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4398
4399         hr = IDirect3DDevice9_EndScene(device);
4400         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4401     }
4402
4403     color = getPixelColor(device, 160, 360);
4404     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4405     color = getPixelColor(device, 160, 120);
4406     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4407        "quad 2 has color %08x, expected 0x00ffff00\n", color);
4408     color = getPixelColor(device, 480, 120);
4409     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4410     color = getPixelColor(device, 480, 360);
4411     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4412
4413     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4414     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4415
4416     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4417     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4418     hr = IDirect3DDevice9_BeginScene(device);
4419     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4420     if(SUCCEEDED(hr))
4421     {
4422         float quad1[] = {
4423             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4424             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4425              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4426              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4427         };
4428         float quad2[] = {
4429             -1.0,       0.0,       0.1,
4430             -1.0,       1.0,       0.1,
4431              0.0,       0.0,       0.1,
4432              0.0,       1.0,       0.1,
4433         };
4434         float quad3[] = {
4435              0.0,       0.0,       0.1,     1.0,
4436              0.0,       1.0,       0.1,     1.0,
4437              1.0,       0.0,       0.1,     1.0,
4438              1.0,       1.0,       0.1,     1.0
4439         };
4440         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4441                            0.0, 0.0, 0.0, 0.0,
4442                            0.0, 0.0, 0.0, 0.0,
4443                            0.0, 1.0, 0.0, 0.0};
4444         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4445                            1.0, 0.0, 0.0, 0.0,
4446                            0.0, 1.0, 0.0, 0.0,
4447                            0.0, 0.0, 1.0, 0.0};
4448         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4449         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4450
4451         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4452          * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4453          * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4454          * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4455          * 4th *input* coordinate.
4456          */
4457         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4458         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4459         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4460         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4461         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4462         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4463
4464         /* None passed */
4465         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4466         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4467         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4468         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4469         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4470         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4471
4472         /* 4 used, 1 passed */
4473         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4474         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4475         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4476         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4477         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4478         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4479
4480         hr = IDirect3DDevice9_EndScene(device);
4481         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4482     }
4483     color = getPixelColor(device, 160, 360);
4484     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4485     color = getPixelColor(device, 160, 120);
4486     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4487     color = getPixelColor(device, 480, 120);
4488     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4489     /* Quad4: unused */
4490
4491     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4492     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4493
4494     IDirect3DVolumeTexture9_Release(volume);
4495
4496     out:
4497     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4498     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4499     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4500     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4501     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4502     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4503     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4504     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4505     IDirect3DVertexDeclaration9_Release(decl);
4506     IDirect3DVertexDeclaration9_Release(decl2);
4507     IDirect3DVertexDeclaration9_Release(decl3);
4508     IDirect3DVertexDeclaration9_Release(decl4);
4509 }
4510
4511 static void texdepth_test(IDirect3DDevice9 *device)
4512 {
4513     IDirect3DPixelShader9 *shader;
4514     HRESULT hr;
4515     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4516     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4517     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4518     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4519     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4520     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4521     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4522     DWORD shader_code[] = {
4523         0xffff0104,                                                                 /* ps_1_4               */
4524         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4525         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4526         0x0000fffd,                                                                 /* phase                */
4527         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4528         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4529         0x0000ffff                                                                  /* end                  */
4530     };
4531     DWORD color;
4532     float vertex[] = {
4533        -1.0,   -1.0,    0.0,
4534         1.0,   -1.0,    1.0,
4535        -1.0,    1.0,    0.0,
4536         1.0,    1.0,    1.0
4537     };
4538
4539     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4540     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4541
4542     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4543     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4544     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4545     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4546     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4547     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4548     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4549     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4550     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4551     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4552
4553     /* Fill the depth buffer with a gradient */
4554     hr = IDirect3DDevice9_BeginScene(device);
4555     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4556     if(SUCCEEDED(hr))
4557     {
4558         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4559         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4560         hr = IDirect3DDevice9_EndScene(device);
4561         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4562     }
4563
4564     /* Now perform the actual tests. Same geometry, but with the shader */
4565     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4566     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4567     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4568     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4569     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4570     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4571
4572     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4573     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4574     hr = IDirect3DDevice9_BeginScene(device);
4575     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4576     if(SUCCEEDED(hr))
4577     {
4578         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4579         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4580
4581         hr = IDirect3DDevice9_EndScene(device);
4582         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4583     }
4584
4585     color = getPixelColor(device, 158, 240);
4586     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4587     color = getPixelColor(device, 162, 240);
4588     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4589
4590     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4591     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4592
4593     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4594     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4595
4596     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4597     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4598     hr = IDirect3DDevice9_BeginScene(device);
4599     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4600     if(SUCCEEDED(hr))
4601     {
4602         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4603         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4604
4605         hr = IDirect3DDevice9_EndScene(device);
4606         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4607     }
4608
4609     color = getPixelColor(device, 318, 240);
4610     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4611     color = getPixelColor(device, 322, 240);
4612     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4613
4614     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4615     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4616
4617     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4618     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4619
4620     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4621     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4622     hr = IDirect3DDevice9_BeginScene(device);
4623     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4624     if(SUCCEEDED(hr))
4625     {
4626         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4627         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4628
4629         hr = IDirect3DDevice9_EndScene(device);
4630         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4631     }
4632
4633     color = getPixelColor(device, 1, 240);
4634     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4635
4636     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4637     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4638
4639     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4640     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4641
4642     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4643     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4644     hr = IDirect3DDevice9_BeginScene(device);
4645     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4646     if(SUCCEEDED(hr))
4647     {
4648         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4649         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4650
4651         hr = IDirect3DDevice9_EndScene(device);
4652         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4653     }
4654     color = getPixelColor(device, 318, 240);
4655     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4656     color = getPixelColor(device, 322, 240);
4657     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4658
4659     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4660     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4661
4662     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4663     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4664
4665     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4666     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4667     hr = IDirect3DDevice9_BeginScene(device);
4668     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4669     if(SUCCEEDED(hr))
4670     {
4671         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4672         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4673
4674         hr = IDirect3DDevice9_EndScene(device);
4675         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4676     }
4677
4678     color = getPixelColor(device, 1, 240);
4679     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4680
4681     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4682     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4683
4684     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4685     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4686
4687     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4688     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4689     hr = IDirect3DDevice9_BeginScene(device);
4690     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4691     if(SUCCEEDED(hr))
4692     {
4693         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4694         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4695
4696         hr = IDirect3DDevice9_EndScene(device);
4697         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4698     }
4699
4700     color = getPixelColor(device, 638, 240);
4701     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4702
4703     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4704     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4705
4706     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4707     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4708
4709     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4710     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4711     hr = IDirect3DDevice9_BeginScene(device);
4712     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4713     if(SUCCEEDED(hr))
4714     {
4715         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4716         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4717
4718         hr = IDirect3DDevice9_EndScene(device);
4719         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4720     }
4721
4722     color = getPixelColor(device, 638, 240);
4723     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4724
4725     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4726     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4727
4728     /* Cleanup */
4729     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4730     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4731     IDirect3DPixelShader9_Release(shader);
4732
4733     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4734     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4735     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4736     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4737 }
4738
4739 static void texkill_test(IDirect3DDevice9 *device)
4740 {
4741     IDirect3DPixelShader9 *shader;
4742     HRESULT hr;
4743     DWORD color;
4744
4745     const float vertex[] = {
4746     /*                          bottom  top    right    left */
4747         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4748          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4749         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4750          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4751     };
4752
4753     DWORD shader_code_11[] = {
4754     0xffff0101,                                                             /* ps_1_1                     */
4755     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4756     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4757     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4758     0x0000ffff                                                              /* end                        */
4759     };
4760     DWORD shader_code_20[] = {
4761     0xffff0200,                                                             /* ps_2_0                     */
4762     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4763     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4764     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4765     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4766     0x0000ffff                                                              /* end                        */
4767     };
4768
4769     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4770     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4771     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4772     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4773
4774     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4775     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4776     hr = IDirect3DDevice9_BeginScene(device);
4777     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4778     if(SUCCEEDED(hr))
4779     {
4780         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4781         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4782         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4783         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4784         hr = IDirect3DDevice9_EndScene(device);
4785         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4786     }
4787     color = getPixelColor(device, 63, 46);
4788     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4789     color = getPixelColor(device, 66, 46);
4790     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4791     color = getPixelColor(device, 63, 49);
4792     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4793     color = getPixelColor(device, 66, 49);
4794     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4795
4796     color = getPixelColor(device, 578, 46);
4797     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4798     color = getPixelColor(device, 575, 46);
4799     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4800     color = getPixelColor(device, 578, 49);
4801     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4802     color = getPixelColor(device, 575, 49);
4803     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4804
4805     color = getPixelColor(device, 63, 430);
4806     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4807     color = getPixelColor(device, 63, 433);
4808     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4809     color = getPixelColor(device, 66, 433);
4810     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4811     color = getPixelColor(device, 66, 430);
4812     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4813
4814     color = getPixelColor(device, 578, 430);
4815     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4816     color = getPixelColor(device, 578, 433);
4817     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4818     color = getPixelColor(device, 575, 433);
4819     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4820     color = getPixelColor(device, 575, 430);
4821     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\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_SetPixelShader(device, NULL);
4827     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4828     IDirect3DPixelShader9_Release(shader);
4829
4830     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4831     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4832     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4833     if(FAILED(hr)) {
4834         skip("Failed to create 2.0 test shader, most likely not supported\n");
4835         return;
4836     }
4837
4838     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4839     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4840     hr = IDirect3DDevice9_BeginScene(device);
4841     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4842     if(SUCCEEDED(hr))
4843     {
4844         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4845         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4846         hr = IDirect3DDevice9_EndScene(device);
4847         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4848     }
4849
4850     color = getPixelColor(device, 63, 46);
4851     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4852     color = getPixelColor(device, 66, 46);
4853     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4854     color = getPixelColor(device, 63, 49);
4855     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4856     color = getPixelColor(device, 66, 49);
4857     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4858
4859     color = getPixelColor(device, 578, 46);
4860     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4861     color = getPixelColor(device, 575, 46);
4862     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4863     color = getPixelColor(device, 578, 49);
4864     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4865     color = getPixelColor(device, 575, 49);
4866     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4867
4868     color = getPixelColor(device, 63, 430);
4869     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4870     color = getPixelColor(device, 63, 433);
4871     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4872     color = getPixelColor(device, 66, 433);
4873     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4874     color = getPixelColor(device, 66, 430);
4875     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4876
4877     color = getPixelColor(device, 578, 430);
4878     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4879     color = getPixelColor(device, 578, 433);
4880     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4881     color = getPixelColor(device, 575, 433);
4882     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4883     color = getPixelColor(device, 575, 430);
4884     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4885
4886     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4887     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4888
4889     /* Cleanup */
4890     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4891     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4892     IDirect3DPixelShader9_Release(shader);
4893 }
4894
4895 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4896 {
4897     IDirect3D9 *d3d9;
4898     HRESULT hr;
4899     IDirect3DTexture9 *texture;
4900     IDirect3DPixelShader9 *shader;
4901     IDirect3DPixelShader9 *shader2;
4902     D3DLOCKED_RECT lr;
4903     DWORD color;
4904     DWORD shader_code[] = {
4905         0xffff0101,                             /* ps_1_1       */
4906         0x00000042, 0xb00f0000,                 /* tex t0       */
4907         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4908         0x0000ffff                              /* end          */
4909     };
4910     DWORD shader_code2[] = {
4911         0xffff0101,                             /* ps_1_1       */
4912         0x00000042, 0xb00f0000,                 /* tex t0       */
4913         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4914         0x0000ffff                              /* end          */
4915     };
4916
4917     float quad[] = {
4918        -1.0,   -1.0,   0.1,     0.5,    0.5,
4919         1.0,   -1.0,   0.1,     0.5,    0.5,
4920        -1.0,    1.0,   0.1,     0.5,    0.5,
4921         1.0,    1.0,   0.1,     0.5,    0.5,
4922     };
4923
4924     memset(&lr, 0, sizeof(lr));
4925     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4926     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4927                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4928     IDirect3D9_Release(d3d9);
4929     if(FAILED(hr)) {
4930         skip("No D3DFMT_X8L8V8U8 support\n");
4931         return;
4932     };
4933
4934     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4935     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4936
4937     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4938     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4939     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4940     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4941     *((DWORD *) lr.pBits) = 0x11ca3141;
4942     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4943     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4944
4945     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4946     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4947     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4948     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4949
4950     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4951     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4952     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4953     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4954     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4955     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4956
4957     hr = IDirect3DDevice9_BeginScene(device);
4958     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4959     if(SUCCEEDED(hr))
4960     {
4961         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4962         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4963
4964         hr = IDirect3DDevice9_EndScene(device);
4965         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4966     }
4967     color = getPixelColor(device, 578, 430);
4968     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4969        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4970     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4971     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4972
4973     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4974     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4975     hr = IDirect3DDevice9_BeginScene(device);
4976     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4977     if(SUCCEEDED(hr))
4978     {
4979         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4980         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4981
4982         hr = IDirect3DDevice9_EndScene(device);
4983         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4984     }
4985     color = getPixelColor(device, 578, 430);
4986     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4987     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4988     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4989
4990     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4991     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4992     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4993     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4994     IDirect3DPixelShader9_Release(shader);
4995     IDirect3DPixelShader9_Release(shader2);
4996     IDirect3DTexture9_Release(texture);
4997 }
4998
4999 static void autogen_mipmap_test(IDirect3DDevice9 *device)
5000 {
5001     HRESULT hr;
5002     IDirect3D9 *d3d;
5003     IDirect3DTexture9 *texture = NULL;
5004     IDirect3DSurface9 *surface;
5005     DWORD color;
5006     const RECT r1 = {256, 256, 512, 512};
5007     const RECT r2 = {512, 256, 768, 512};
5008     const RECT r3 = {256, 512, 512, 768};
5009     const RECT r4 = {512, 512, 768, 768};
5010     unsigned int x, y;
5011     D3DLOCKED_RECT lr;
5012     memset(&lr, 0, sizeof(lr));
5013
5014     IDirect3DDevice9_GetDirect3D(device, &d3d);
5015     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5016        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
5017         skip("No autogenmipmap support\n");
5018         IDirect3D9_Release(d3d);
5019         return;
5020     }
5021     IDirect3D9_Release(d3d);
5022
5023     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5024     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5025
5026     /* Make the mipmap big, so that a smaller mipmap is used
5027      */
5028     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5029                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5030     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5031
5032     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5033     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5034     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5035     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5036     for(y = 0; y < 1024; y++) {
5037         for(x = 0; x < 1024; x++) {
5038             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5039             POINT pt;
5040
5041             pt.x = x;
5042             pt.y = y;
5043             if(PtInRect(&r1, pt)) {
5044                 *dst = 0xffff0000;
5045             } else if(PtInRect(&r2, pt)) {
5046                 *dst = 0xff00ff00;
5047             } else if(PtInRect(&r3, pt)) {
5048                 *dst = 0xff0000ff;
5049             } else if(PtInRect(&r4, pt)) {
5050                 *dst = 0xff000000;
5051             } else {
5052                 *dst = 0xffffffff;
5053             }
5054         }
5055     }
5056     hr = IDirect3DSurface9_UnlockRect(surface);
5057     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5058     IDirect3DSurface9_Release(surface);
5059
5060     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5061     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5062     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5063     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5064
5065     hr = IDirect3DDevice9_BeginScene(device);
5066     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5067     if(SUCCEEDED(hr)) {
5068         const float quad[] =  {
5069            -0.5,   -0.5,    0.1,    0.0,    0.0,
5070            -0.5,    0.5,    0.1,    0.0,    1.0,
5071             0.5,   -0.5,    0.1,    1.0,    0.0,
5072             0.5,    0.5,    0.1,    1.0,    1.0
5073         };
5074
5075         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5076         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5077         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5078         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5079         hr = IDirect3DDevice9_EndScene(device);
5080         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5081     }
5082     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5083     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5084     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
5085     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5086     IDirect3DTexture9_Release(texture);
5087
5088     color = getPixelColor(device, 200, 200);
5089     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5090     color = getPixelColor(device, 280, 200);
5091     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5092     color = getPixelColor(device, 360, 200);
5093     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5094     color = getPixelColor(device, 440, 200);
5095     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5096     color = getPixelColor(device, 200, 270);
5097     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5098     color = getPixelColor(device, 280, 270);
5099     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5100     color = getPixelColor(device, 360, 270);
5101     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5102     color = getPixelColor(device, 440, 270);
5103     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5104     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5105     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5106 }
5107
5108 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
5109 {
5110     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5111     IDirect3DVertexDeclaration9 *decl;
5112     HRESULT hr;
5113     DWORD color;
5114     DWORD shader_code_11[] =  {
5115         0xfffe0101,                                         /* vs_1_1           */
5116         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5117         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5118         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5119         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5120         0x0000ffff                                          /* end              */
5121     };
5122     DWORD shader_code_11_2[] =  {
5123         0xfffe0101,                                         /* vs_1_1           */
5124         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
5125         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
5126         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5127         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5128         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5129         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5130         0x0000ffff                                          /* end              */
5131     };
5132     DWORD shader_code_20[] =  {
5133         0xfffe0200,                                         /* vs_2_0           */
5134         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5135         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5136         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5137         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5138         0x0000ffff                                          /* end              */
5139     };
5140     DWORD shader_code_20_2[] =  {
5141         0xfffe0200,                                         /* vs_2_0           */
5142         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
5143         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
5144         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
5145         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5146         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
5147         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
5148         0x0000ffff                                          /* end              */
5149     };
5150     static const D3DVERTEXELEMENT9 decl_elements[] = {
5151         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5152         D3DDECL_END()
5153     };
5154     float quad1[] = {
5155         -1.0,   -1.0,   0.1,
5156          0.0,   -1.0,   0.1,
5157         -1.0,    0.0,   0.1,
5158          0.0,    0.0,   0.1
5159     };
5160     float quad2[] = {
5161          0.0,   -1.0,   0.1,
5162          1.0,   -1.0,   0.1,
5163          0.0,    0.0,   0.1,
5164          1.0,    0.0,   0.1
5165     };
5166     float quad3[] = {
5167          0.0,    0.0,   0.1,
5168          1.0,    0.0,   0.1,
5169          0.0,    1.0,   0.1,
5170          1.0,    1.0,   0.1
5171     };
5172     float quad4[] = {
5173         -1.0,    0.0,   0.1,
5174          0.0,    0.0,   0.1,
5175         -1.0,    1.0,   0.1,
5176          0.0,    1.0,   0.1
5177     };
5178     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
5179     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
5180
5181     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5182     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5183
5184     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
5185     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5186     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
5187     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5188     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
5189     if(FAILED(hr)) shader_20 = NULL;
5190     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
5191     if(FAILED(hr)) shader_20_2 = NULL;
5192     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5193     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5194
5195     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
5196     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5197     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
5198     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5199     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5200     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5201
5202     hr = IDirect3DDevice9_BeginScene(device);
5203     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5204     if(SUCCEEDED(hr))
5205     {
5206         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
5207         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5208         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5209         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5210
5211         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
5212         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5213         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5214         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5215
5216         if(shader_20) {
5217             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
5218             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5219             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5220             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5221         }
5222
5223         if(shader_20_2) {
5224             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
5225             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5226             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5227             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5228         }
5229
5230         hr = IDirect3DDevice9_EndScene(device);
5231         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5232     }
5233
5234     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5235     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5236     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5237     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5238
5239     color = getPixelColor(device, 160, 360);
5240     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5241        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
5242     color = getPixelColor(device, 480, 360);
5243     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5244        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
5245     if(shader_20) {
5246         color = getPixelColor(device, 480, 120);
5247         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5248            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
5249     }
5250     if(shader_20_2) {
5251         color = getPixelColor(device, 160, 120);
5252         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5253            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5254     }
5255     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5256     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5257
5258     IDirect3DVertexDeclaration9_Release(decl);
5259     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
5260     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
5261     IDirect3DVertexShader9_Release(shader_11_2);
5262     IDirect3DVertexShader9_Release(shader_11);
5263 }
5264
5265 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
5266 {
5267     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
5268     HRESULT hr;
5269     DWORD color;
5270     DWORD shader_code_11[] =  {
5271         0xffff0101,                                         /* ps_1_1           */
5272         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5273         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5274         0x0000ffff                                          /* end              */
5275     };
5276     DWORD shader_code_12[] =  {
5277         0xffff0102,                                         /* ps_1_2           */
5278         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5279         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5280         0x0000ffff                                          /* end              */
5281     };
5282     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
5283      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
5284      * During development of this test, 1.3 shaders were verified too
5285      */
5286     DWORD shader_code_14[] =  {
5287         0xffff0104,                                         /* ps_1_4           */
5288         /* Try to make one constant local. It gets clamped too, although the binary contains
5289          * the bigger numbers
5290          */
5291         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
5292         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5293         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5294         0x0000ffff                                          /* end              */
5295     };
5296     DWORD shader_code_20[] =  {
5297         0xffff0200,                                         /* ps_2_0           */
5298         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
5299         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
5300         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
5301         0x0000ffff                                          /* end              */
5302     };
5303     float quad1[] = {
5304         -1.0,   -1.0,   0.1,
5305          0.0,   -1.0,   0.1,
5306         -1.0,    0.0,   0.1,
5307          0.0,    0.0,   0.1
5308     };
5309     float quad2[] = {
5310          0.0,   -1.0,   0.1,
5311          1.0,   -1.0,   0.1,
5312          0.0,    0.0,   0.1,
5313          1.0,    0.0,   0.1
5314     };
5315     float quad3[] = {
5316          0.0,    0.0,   0.1,
5317          1.0,    0.0,   0.1,
5318          0.0,    1.0,   0.1,
5319          1.0,    1.0,   0.1
5320     };
5321     float quad4[] = {
5322         -1.0,    0.0,   0.1,
5323          0.0,    0.0,   0.1,
5324         -1.0,    1.0,   0.1,
5325          0.0,    1.0,   0.1
5326     };
5327     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
5328     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
5329
5330     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5331     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5332
5333     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5334     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5335     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5336     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5337     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5338     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5339     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
5340     if(FAILED(hr)) shader_20 = NULL;
5341
5342     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5343     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5344     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5345     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5346     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5347     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5348
5349     hr = IDirect3DDevice9_BeginScene(device);
5350     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5351     if(SUCCEEDED(hr))
5352     {
5353         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5354         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5355         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5356         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5357
5358         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5359         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5360         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5361         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5362
5363         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5364         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5365         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5366         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5367
5368         if(shader_20) {
5369             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
5370             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5371             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5372             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5373         }
5374
5375         hr = IDirect3DDevice9_EndScene(device);
5376         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5377     }
5378     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5379     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5380
5381     color = getPixelColor(device, 160, 360);
5382     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5383        "quad 1 has color %08x, expected 0x00808000\n", color);
5384     color = getPixelColor(device, 480, 360);
5385     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5386        "quad 2 has color %08x, expected 0x00808000\n", color);
5387     color = getPixelColor(device, 480, 120);
5388     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5389        "quad 3 has color %08x, expected 0x00808000\n", color);
5390     if(shader_20) {
5391         color = getPixelColor(device, 160, 120);
5392         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5393            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5394     }
5395     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5396     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5397
5398     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5399     IDirect3DPixelShader9_Release(shader_14);
5400     IDirect3DPixelShader9_Release(shader_12);
5401     IDirect3DPixelShader9_Release(shader_11);
5402 }
5403
5404 static void dp2add_ps_test(IDirect3DDevice9 *device)
5405 {
5406     IDirect3DPixelShader9 *shader_dp2add = NULL;
5407     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5408     HRESULT hr;
5409     DWORD color;
5410
5411     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
5412      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5413      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
5414      * r0 first.
5415      * The result here for the r,g,b components should be roughly 0.5:
5416      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5417     static const DWORD shader_code_dp2add[] =  {
5418         0xffff0200,                                                             /* ps_2_0                       */
5419         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
5420
5421         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5422         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
5423
5424         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
5425         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5426         0x0000ffff                                                              /* end                          */
5427     };
5428
5429     /* Test the _sat modifier, too.  Result here should be:
5430      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5431      *      _SAT: ==> 1.0
5432      *   ADD: (1.0 + -0.5) = 0.5
5433      */
5434     static const DWORD shader_code_dp2add_sat[] =  {
5435         0xffff0200,                                                             /* ps_2_0                           */
5436         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
5437
5438         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
5439         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
5440         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5441
5442         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5443         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5444         0x0000ffff                                                              /* end                              */
5445     };
5446
5447     const float quad[] = {
5448         -1.0,   -1.0,   0.1,
5449          1.0,   -1.0,   0.1,
5450         -1.0,    1.0,   0.1,
5451          1.0,    1.0,   0.1
5452     };
5453
5454
5455     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5456     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5457
5458     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5459     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5460
5461     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5462     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5463
5464     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5465     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5466
5467     if (shader_dp2add) {
5468
5469         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5470         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5471
5472         hr = IDirect3DDevice9_BeginScene(device);
5473         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5474         if(SUCCEEDED(hr))
5475         {
5476             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5477             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5478
5479             hr = IDirect3DDevice9_EndScene(device);
5480             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5481         }
5482
5483         color = getPixelColor(device, 360, 240);
5484         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5485                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5486
5487         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5488         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5489
5490         IDirect3DPixelShader9_Release(shader_dp2add);
5491     } else {
5492         skip("dp2add shader creation failed\n");
5493     }
5494
5495     if (shader_dp2add_sat) {
5496
5497         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5498         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5499
5500         hr = IDirect3DDevice9_BeginScene(device);
5501         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5502         if(SUCCEEDED(hr))
5503         {
5504             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5505             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5506
5507             hr = IDirect3DDevice9_EndScene(device);
5508             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5509         }
5510
5511         color = getPixelColor(device, 360, 240);
5512         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5513                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5514
5515         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5516         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5517
5518         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5519     } else {
5520         skip("dp2add shader creation failed\n");
5521     }
5522
5523     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5524     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5525 }
5526
5527 static void cnd_test(IDirect3DDevice9 *device)
5528 {
5529     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5530     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5531     HRESULT hr;
5532     DWORD color;
5533     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5534      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5535      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5536      */
5537     DWORD shader_code_11[] =  {
5538         0xffff0101,                                                                 /* ps_1_1               */
5539         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5540         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5541         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5542         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5543         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5544         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5545         0x0000ffff                                                                  /* end                  */
5546     };
5547     DWORD shader_code_12[] =  {
5548         0xffff0102,                                                                 /* ps_1_2               */
5549         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5550         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5551         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5552         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5553         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5554         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5555         0x0000ffff                                                                  /* end                  */
5556     };
5557     DWORD shader_code_13[] =  {
5558         0xffff0103,                                                                 /* ps_1_3               */
5559         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5560         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5561         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5562         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5563         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5564         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5565         0x0000ffff                                                                  /* end                  */
5566     };
5567     DWORD shader_code_14[] =  {
5568         0xffff0104,                                                                 /* ps_1_3               */
5569         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5570         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5571         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5572         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5573         0x0000ffff                                                                  /* end                  */
5574     };
5575
5576     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5577      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5578      * set by the compiler, it was added manually after compilation. Note that the COISSUE
5579      * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5580      * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5581      * well enough.
5582      *
5583      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5584      * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5585      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5586      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5587      */
5588     DWORD shader_code_11_coissue[] =  {
5589         0xffff0101,                                                             /* ps_1_1                   */
5590         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5591         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5592         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5593         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5594         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5595         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5596         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5597         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5598         /* 0x40000000 = D3DSI_COISSUE */
5599         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5600         0x0000ffff                                                              /* end                      */
5601     };
5602     DWORD shader_code_12_coissue[] =  {
5603         0xffff0102,                                                             /* ps_1_2                   */
5604         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5605         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5606         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5607         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5608         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5609         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5610         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5611         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5612         /* 0x40000000 = D3DSI_COISSUE */
5613         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5614         0x0000ffff                                                              /* end                      */
5615     };
5616     DWORD shader_code_13_coissue[] =  {
5617         0xffff0103,                                                             /* ps_1_3                   */
5618         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5619         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5620         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5621         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5622         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5623         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5624         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5625         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5626         /* 0x40000000 = D3DSI_COISSUE */
5627         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5628         0x0000ffff                                                              /* end                      */
5629     };
5630     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5631      * compare against 0.5
5632      */
5633     DWORD shader_code_14_coissue[] =  {
5634         0xffff0104,                                                             /* ps_1_4                   */
5635         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5636         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5637         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5638         /* 0x40000000 = D3DSI_COISSUE */
5639         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5640         0x0000ffff                                                              /* end                      */
5641     };
5642     float quad1[] = {
5643         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5644          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5645         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5646          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5647     };
5648     float quad2[] = {
5649          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5650          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5651          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5652          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5653     };
5654     float quad3[] = {
5655          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5656          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5657          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5658          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5659     };
5660     float quad4[] = {
5661         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5662          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5663         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5664          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5665     };
5666     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5667     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5668     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5669     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5670
5671     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5672     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5673
5674     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5675     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5676     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5677     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5678     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5679     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5680     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5681     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5682     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5683     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5684     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5685     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5686     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5687     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5688     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5689     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5690
5691     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5692     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5693     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5694     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5695     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5696     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5697
5698     hr = IDirect3DDevice9_BeginScene(device);
5699     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5700     if(SUCCEEDED(hr))
5701     {
5702         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5703         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5704         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5705         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5706
5707         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5708         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5709         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5710         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5711
5712         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5713         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5714         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5715         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5716
5717         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5718         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5719         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5720         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5721
5722         hr = IDirect3DDevice9_EndScene(device);
5723         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5724     }
5725
5726     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5727     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5728
5729     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5730     color = getPixelColor(device, 158, 118);
5731     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5732     color = getPixelColor(device, 162, 118);
5733     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5734     color = getPixelColor(device, 158, 122);
5735     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5736     color = getPixelColor(device, 162, 122);
5737     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5738
5739     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5740     color = getPixelColor(device, 158, 358);
5741     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5742     color = getPixelColor(device, 162, 358);
5743     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5744         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5745     color = getPixelColor(device, 158, 362);
5746     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5747     color = getPixelColor(device, 162, 362);
5748     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5749         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5750
5751     /* 1.2 shader */
5752     color = getPixelColor(device, 478, 358);
5753     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5754     color = getPixelColor(device, 482, 358);
5755     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5756         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5757     color = getPixelColor(device, 478, 362);
5758     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5759     color = getPixelColor(device, 482, 362);
5760     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5761         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5762
5763     /* 1.3 shader */
5764     color = getPixelColor(device, 478, 118);
5765     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5766     color = getPixelColor(device, 482, 118);
5767     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5768         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5769     color = getPixelColor(device, 478, 122);
5770     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5771     color = getPixelColor(device, 482, 122);
5772     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5773         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5774
5775     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5776     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5777
5778     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5779     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5780     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5781     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5782     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5783     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5784
5785     hr = IDirect3DDevice9_BeginScene(device);
5786     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5787     if(SUCCEEDED(hr))
5788     {
5789         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5790         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5791         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5792         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5793
5794         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5795         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5796         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5797         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5798
5799         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5800         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5801         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5802         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5803
5804         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5805         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5806         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5807         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5808
5809         hr = IDirect3DDevice9_EndScene(device);
5810         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5811     }
5812
5813     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5814     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5815
5816     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5817      * that we swapped the values in c1 and c2 to make the other tests return some color
5818      */
5819     color = getPixelColor(device, 158, 118);
5820     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5821     color = getPixelColor(device, 162, 118);
5822     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5823     color = getPixelColor(device, 158, 122);
5824     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5825     color = getPixelColor(device, 162, 122);
5826     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5827
5828     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5829      * (The Win7 nvidia driver always selects c2)
5830      */
5831     color = getPixelColor(device, 158, 358);
5832     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5833         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5834     color = getPixelColor(device, 162, 358);
5835     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5836         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5837     color = getPixelColor(device, 158, 362);
5838     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5839         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5840     color = getPixelColor(device, 162, 362);
5841     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5842         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5843
5844     /* 1.2 shader */
5845     color = getPixelColor(device, 478, 358);
5846     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5847         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5848     color = getPixelColor(device, 482, 358);
5849     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5850         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5851     color = getPixelColor(device, 478, 362);
5852     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5853         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5854     color = getPixelColor(device, 482, 362);
5855     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5856         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5857
5858     /* 1.3 shader */
5859     color = getPixelColor(device, 478, 118);
5860     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5861         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5862     color = getPixelColor(device, 482, 118);
5863     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5864         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5865     color = getPixelColor(device, 478, 122);
5866     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5867         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5868     color = getPixelColor(device, 482, 122);
5869     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5870         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5871
5872     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5873     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5874
5875     IDirect3DPixelShader9_Release(shader_14_coissue);
5876     IDirect3DPixelShader9_Release(shader_13_coissue);
5877     IDirect3DPixelShader9_Release(shader_12_coissue);
5878     IDirect3DPixelShader9_Release(shader_11_coissue);
5879     IDirect3DPixelShader9_Release(shader_14);
5880     IDirect3DPixelShader9_Release(shader_13);
5881     IDirect3DPixelShader9_Release(shader_12);
5882     IDirect3DPixelShader9_Release(shader_11);
5883 }
5884
5885 static void nested_loop_test(IDirect3DDevice9 *device) {
5886     const DWORD shader_code[] = {
5887         0xffff0300,                                                             /* ps_3_0               */
5888         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5889         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5890         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5891         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5892         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5893         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5894         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5895         0x0000001d,                                                             /* endloop              */
5896         0x0000001d,                                                             /* endloop              */
5897         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5898         0x0000ffff                                                              /* end                  */
5899     };
5900     const DWORD vshader_code[] = {
5901         0xfffe0300,                                                             /* vs_3_0               */
5902         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
5903         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
5904         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
5905         0x0000ffff                                                              /* end                  */
5906     };
5907     IDirect3DPixelShader9 *shader;
5908     IDirect3DVertexShader9 *vshader;
5909     HRESULT hr;
5910     DWORD color;
5911     const float quad[] = {
5912         -1.0,   -1.0,   0.1,
5913          1.0,   -1.0,   0.1,
5914         -1.0,    1.0,   0.1,
5915          1.0,    1.0,   0.1
5916     };
5917
5918     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5919     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5920     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5921     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5922     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5923     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5924     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5925     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5926     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5927     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5928     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5929     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5930
5931     hr = IDirect3DDevice9_BeginScene(device);
5932     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5933     if(SUCCEEDED(hr))
5934     {
5935         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5936         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5937         hr = IDirect3DDevice9_EndScene(device);
5938         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5939     }
5940
5941     color = getPixelColor(device, 360, 240);
5942     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5943        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5944
5945     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5946     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5947
5948     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5949     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5950     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5951     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5952     IDirect3DPixelShader9_Release(shader);
5953     IDirect3DVertexShader9_Release(vshader);
5954 }
5955
5956 struct varying_test_struct
5957 {
5958     const DWORD             *shader_code;
5959     IDirect3DPixelShader9   *shader;
5960     DWORD                   color, color_rhw;
5961     const char              *name;
5962     BOOL                    todo, todo_rhw;
5963 };
5964
5965 struct hugeVertex
5966 {
5967     float pos_x,        pos_y,      pos_z,      rhw;
5968     float weight_1,     weight_2,   weight_3,   weight_4;
5969     float index_1,      index_2,    index_3,    index_4;
5970     float normal_1,     normal_2,   normal_3,   normal_4;
5971     float fog_1,        fog_2,      fog_3,      fog_4;
5972     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5973     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5974     float binormal_1,   binormal_2, binormal_3, binormal_4;
5975     float depth_1,      depth_2,    depth_3,    depth_4;
5976     DWORD diffuse, specular;
5977 };
5978
5979 static void pretransformed_varying_test(IDirect3DDevice9 *device) {
5980     /* dcl_position: fails to compile */
5981     const DWORD blendweight_code[] = {
5982         0xffff0300,                             /* ps_3_0                   */
5983         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5984         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5985         0x0000ffff                              /* end                      */
5986     };
5987     const DWORD blendindices_code[] = {
5988         0xffff0300,                             /* ps_3_0                   */
5989         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5990         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5991         0x0000ffff                              /* end                      */
5992     };
5993     const DWORD normal_code[] = {
5994         0xffff0300,                             /* ps_3_0                   */
5995         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5996         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5997         0x0000ffff                              /* end                      */
5998     };
5999     /* psize: fails? */
6000     const DWORD texcoord0_code[] = {
6001         0xffff0300,                             /* ps_3_0                   */
6002         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
6003         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6004         0x0000ffff                              /* end                      */
6005     };
6006     const DWORD tangent_code[] = {
6007         0xffff0300,                             /* ps_3_0                   */
6008         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
6009         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6010         0x0000ffff                              /* end                      */
6011     };
6012     const DWORD binormal_code[] = {
6013         0xffff0300,                             /* ps_3_0                   */
6014         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
6015         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6016         0x0000ffff                              /* end                      */
6017     };
6018     /* tessfactor: fails */
6019     /* positiont: fails */
6020     const DWORD color_code[] = {
6021         0xffff0300,                             /* ps_3_0                   */
6022         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
6023         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6024         0x0000ffff                              /* end                      */
6025     };
6026     const DWORD fog_code[] = {
6027         0xffff0300,                             /* ps_3_0                   */
6028         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
6029         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6030         0x0000ffff                              /* end                      */
6031     };
6032     const DWORD depth_code[] = {
6033         0xffff0300,                             /* ps_3_0                   */
6034         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
6035         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6036         0x0000ffff                              /* end                      */
6037     };
6038     const DWORD specular_code[] = {
6039         0xffff0300,                             /* ps_3_0                   */
6040         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
6041         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
6042         0x0000ffff                              /* end                      */
6043     };
6044     /* sample: fails */
6045
6046     struct varying_test_struct tests[] = {
6047        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
6048        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
6049        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
6050        /* Why does dx not forward the texcoord? */
6051        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
6052        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
6053        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
6054        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
6055        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
6056        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
6057        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
6058     };
6059     /* Declare a monster vertex type :-) */
6060     static const D3DVERTEXELEMENT9 decl_elements[] = {
6061         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6062         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
6063         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
6064         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
6065         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
6066         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6067         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
6068         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
6069         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
6070         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6071         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
6072         D3DDECL_END()
6073     };
6074     struct hugeVertex data[4] = {
6075         {
6076             -1.0,   -1.0,   0.1,    1.0,
6077              0.1,    0.1,   0.1,    0.1,
6078              0.2,    0.2,   0.2,    0.2,
6079              0.3,    0.3,   0.3,    0.3,
6080              0.4,    0.4,   0.4,    0.4,
6081              0.50,   0.55,  0.55,   0.55,
6082              0.6,    0.6,   0.6,    0.7,
6083              0.7,    0.7,   0.7,    0.6,
6084              0.8,    0.8,   0.8,    0.8,
6085              0xe6e6e6e6, /* 0.9 * 256 */
6086              0x224488ff  /* Nothing special */
6087         },
6088         {
6089              1.0,   -1.0,   0.1,    1.0,
6090              0.1,    0.1,   0.1,    0.1,
6091              0.2,    0.2,   0.2,    0.2,
6092              0.3,    0.3,   0.3,    0.3,
6093              0.4,    0.4,   0.4,    0.4,
6094              0.50,   0.55,  0.55,   0.55,
6095              0.6,    0.6,   0.6,    0.7,
6096              0.7,    0.7,   0.7,    0.6,
6097              0.8,    0.8,   0.8,    0.8,
6098              0xe6e6e6e6, /* 0.9 * 256 */
6099              0x224488ff /* Nothing special */
6100         },
6101         {
6102             -1.0,    1.0,   0.1,    1.0,
6103              0.1,    0.1,   0.1,    0.1,
6104              0.2,    0.2,   0.2,    0.2,
6105              0.3,    0.3,   0.3,    0.3,
6106              0.4,    0.4,   0.4,    0.4,
6107              0.50,   0.55,  0.55,   0.55,
6108              0.6,    0.6,   0.6,    0.7,
6109              0.7,    0.7,   0.7,    0.6,
6110              0.8,    0.8,   0.8,    0.8,
6111              0xe6e6e6e6, /* 0.9 * 256 */
6112              0x224488ff /* Nothing special */
6113         },
6114         {
6115              1.0,    1.0,   0.1,    1.0,
6116              0.1,    0.1,   0.1,    0.1,
6117              0.2,    0.2,   0.2,    0.2,
6118              0.3,    0.3,   0.3,    0.3,
6119              0.4,    0.4,   0.4,    0.4,
6120              0.50,   0.55,  0.55,   0.55,
6121              0.6,    0.6,   0.6,    0.7,
6122              0.7,    0.7,   0.7,    0.6,
6123              0.8,    0.8,   0.8,    0.8,
6124              0xe6e6e6e6, /* 0.9 * 256 */
6125              0x224488ff /* Nothing special */
6126         },
6127     };
6128     struct hugeVertex data2[4];
6129     IDirect3DVertexDeclaration9 *decl;
6130     HRESULT hr;
6131     unsigned int i;
6132     DWORD color, r, g, b, r_e, g_e, b_e;
6133
6134     memcpy(data2, data, sizeof(data2));
6135     data2[0].pos_x = 0;     data2[0].pos_y = 0;
6136     data2[1].pos_x = 640;   data2[1].pos_y = 0;
6137     data2[2].pos_x = 0;     data2[2].pos_y = 480;
6138     data2[3].pos_x = 640;   data2[3].pos_y = 480;
6139
6140     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6141     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6142     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6143     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6144
6145     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6146     {
6147         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
6148         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
6149            tests[i].name, hr);
6150     }
6151
6152     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6153     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6154     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6155     {
6156         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6157         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6158
6159         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
6160         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6161
6162         hr = IDirect3DDevice9_BeginScene(device);
6163         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6164         if(SUCCEEDED(hr))
6165         {
6166             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
6167             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6168             hr = IDirect3DDevice9_EndScene(device);
6169             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6170         }
6171
6172         color = getPixelColor(device, 360, 240);
6173         r = color & 0x00ff0000 >> 16;
6174         g = color & 0x0000ff00 >>  8;
6175         b = color & 0x000000ff;
6176         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
6177         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
6178         b_e = tests[i].color_rhw & 0x000000ff;
6179
6180         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6181         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6182
6183         if(tests[i].todo_rhw) {
6184             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
6185              * pipeline
6186              */
6187             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6188                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
6189                          tests[i].name, color, tests[i].color_rhw);
6190         } else {
6191             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
6192                "Test %s returned color 0x%08x, expected 0x%08x\n",
6193                tests[i].name, color, tests[i].color_rhw);
6194         }
6195     }
6196
6197     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
6198     {
6199         IDirect3DPixelShader9_Release(tests[i].shader);
6200     }
6201
6202     IDirect3DVertexDeclaration9_Release(decl);
6203 }
6204
6205 static void test_compare_instructions(IDirect3DDevice9 *device)
6206 {
6207     DWORD shader_sge_vec_code[] = {
6208         0xfffe0101,                                         /* vs_1_1                   */
6209         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6210         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6211         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6212         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
6213         0x0000ffff                                          /* end                      */
6214     };
6215     DWORD shader_slt_vec_code[] = {
6216         0xfffe0101,                                         /* vs_1_1                   */
6217         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6218         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6219         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6220         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
6221         0x0000ffff                                          /* end                      */
6222     };
6223     DWORD shader_sge_scalar_code[] = {
6224         0xfffe0101,                                         /* vs_1_1                   */
6225         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6226         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6227         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6228         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
6229         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
6230         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
6231         0x0000ffff                                          /* end                      */
6232     };
6233     DWORD shader_slt_scalar_code[] = {
6234         0xfffe0101,                                         /* vs_1_1                   */
6235         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6236         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6237         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6238         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
6239         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
6240         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
6241         0x0000ffff                                          /* end                      */
6242     };
6243     IDirect3DVertexShader9 *shader_sge_vec;
6244     IDirect3DVertexShader9 *shader_slt_vec;
6245     IDirect3DVertexShader9 *shader_sge_scalar;
6246     IDirect3DVertexShader9 *shader_slt_scalar;
6247     HRESULT hr, color;
6248     float quad1[] =  {
6249         -1.0,   -1.0,   0.1,
6250          0.0,   -1.0,   0.1,
6251         -1.0,    0.0,   0.1,
6252          0.0,    0.0,   0.1
6253     };
6254     float quad2[] =  {
6255          0.0,   -1.0,   0.1,
6256          1.0,   -1.0,   0.1,
6257          0.0,    0.0,   0.1,
6258          1.0,    0.0,   0.1
6259     };
6260     float quad3[] =  {
6261         -1.0,    0.0,   0.1,
6262          0.0,    0.0,   0.1,
6263         -1.0,    1.0,   0.1,
6264          0.0,    1.0,   0.1
6265     };
6266     float quad4[] =  {
6267          0.0,    0.0,   0.1,
6268          1.0,    0.0,   0.1,
6269          0.0,    1.0,   0.1,
6270          1.0,    1.0,   0.1
6271     };
6272     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6273     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6274
6275     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6276     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6277
6278     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6279     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6280     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6281     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6282     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6283     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6284     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6285     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6286     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6287     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6288     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6289     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6290     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6291     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6292
6293     hr = IDirect3DDevice9_BeginScene(device);
6294     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6295     if(SUCCEEDED(hr))
6296     {
6297         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6298         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6299         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6300         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6301
6302         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6303         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6304         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6305         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6306
6307         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6308         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6309         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6310         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6311
6312         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6313         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6314
6315         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6316         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6317         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6318         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6319
6320         hr = IDirect3DDevice9_EndScene(device);
6321         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6322     }
6323
6324     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6325     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6326
6327     color = getPixelColor(device, 160, 360);
6328     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6329     color = getPixelColor(device, 480, 360);
6330     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6331     color = getPixelColor(device, 160, 120);
6332     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6333     color = getPixelColor(device, 480, 160);
6334     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6335
6336     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6337     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6338
6339     IDirect3DVertexShader9_Release(shader_sge_vec);
6340     IDirect3DVertexShader9_Release(shader_slt_vec);
6341     IDirect3DVertexShader9_Release(shader_sge_scalar);
6342     IDirect3DVertexShader9_Release(shader_slt_scalar);
6343 }
6344
6345 static void test_vshader_input(IDirect3DDevice9 *device)
6346 {
6347     static const DWORD swapped_shader_code_3[] =
6348     {
6349         0xfffe0300,                                         /* vs_3_0               */
6350         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6351         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6352         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6353         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6354         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6355         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6356         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6357         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6358         0x0000ffff                                          /* end                  */
6359     };
6360     static const DWORD swapped_shader_code_1[] =
6361     {
6362         0xfffe0101,                                         /* vs_1_1               */
6363         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6364         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6365         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6366         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6367         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6368         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6369         0x0000ffff                                          /* end                  */
6370     };
6371     static const DWORD swapped_shader_code_2[] =
6372     {
6373         0xfffe0200,                                         /* vs_2_0               */
6374         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6375         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6376         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6377         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6378         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6379         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6380         0x0000ffff                                          /* end                  */
6381     };
6382     static const DWORD texcoord_color_shader_code_3[] =
6383     {
6384         0xfffe0300,                                         /* vs_3_0               */
6385         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6386         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6387         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6388         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6389         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6390         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6391         0x0000ffff                                          /* end                  */
6392     };
6393     static const DWORD texcoord_color_shader_code_2[] =
6394     {
6395         0xfffe0200,                                         /* vs_2_0               */
6396         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6397         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6398         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6399         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6400         0x0000ffff                                          /* end                  */
6401     };
6402     static const DWORD texcoord_color_shader_code_1[] =
6403     {
6404         0xfffe0101,                                         /* vs_1_1               */
6405         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6406         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6407         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6408         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6409         0x0000ffff                                          /* end                  */
6410     };
6411     static const DWORD color_color_shader_code_3[] =
6412     {
6413         0xfffe0300,                                         /* vs_3_0               */
6414         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6415         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6416         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6417         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6418         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6419         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6420         0x0000ffff                                          /* end                  */
6421     };
6422     static const DWORD color_color_shader_code_2[] =
6423     {
6424         0xfffe0200,                                         /* vs_2_0               */
6425         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6426         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6427         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6428         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6429         0x0000ffff                                          /* end                  */
6430     };
6431     static const DWORD color_color_shader_code_1[] =
6432     {
6433         0xfffe0101,                                         /* vs_1_1               */
6434         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6435         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6436         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6437         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6438         0x0000ffff                                          /* end                  */
6439     };
6440     static const DWORD ps3_code[] =
6441     {
6442         0xffff0300,                                         /* ps_3_0               */
6443         0x0200001f, 0x8000000a, 0x900f0000,                 /* dcl_color0 v0        */
6444         0x02000001, 0x800f0800, 0x90e40000,                 /* mov oC0, v0          */
6445         0x0000ffff                                          /* end                  */
6446     };
6447     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6448     IDirect3DPixelShader9 *ps;
6449     HRESULT hr;
6450     DWORD color;
6451     float quad1[] =  {
6452         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6453          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6454         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6455          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6456     };
6457     float quad2[] =  {
6458          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6459          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6460          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6461          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6462     };
6463     float quad3[] =  {
6464         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6465          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6466         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6467          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6468     };
6469     float quad4[] =  {
6470          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6471          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6472          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6473          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6474     };
6475     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6476         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6477         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6478         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6479         D3DDECL_END()
6480     };
6481     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6482         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6483         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6484         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6485         D3DDECL_END()
6486     };
6487     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6488         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6489         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6490         D3DDECL_END()
6491     };
6492     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6493         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6494         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6495         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6496         D3DDECL_END()
6497     };
6498     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6499         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6500         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6501         D3DDECL_END()
6502     };
6503     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6504         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6505         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6506         D3DDECL_END()
6507     };
6508     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6509         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6510         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6511         D3DDECL_END()
6512     };
6513     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6514         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6515         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6516         D3DDECL_END()
6517     };
6518     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6519     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6520     unsigned int i;
6521     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6522     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6523
6524     struct vertex quad1_color[] =  {
6525        {-1.0,   -1.0,   0.1,    0x00ff8040},
6526        { 0.0,   -1.0,   0.1,    0x00ff8040},
6527        {-1.0,    0.0,   0.1,    0x00ff8040},
6528        { 0.0,    0.0,   0.1,    0x00ff8040}
6529     };
6530     struct vertex quad2_color[] =  {
6531        { 0.0,   -1.0,   0.1,    0x00ff8040},
6532        { 1.0,   -1.0,   0.1,    0x00ff8040},
6533        { 0.0,    0.0,   0.1,    0x00ff8040},
6534        { 1.0,    0.0,   0.1,    0x00ff8040}
6535     };
6536     struct vertex quad3_color[] =  {
6537        {-1.0,    0.0,   0.1,    0x00ff8040},
6538        { 0.0,    0.0,   0.1,    0x00ff8040},
6539        {-1.0,    1.0,   0.1,    0x00ff8040},
6540        { 0.0,    1.0,   0.1,    0x00ff8040}
6541     };
6542     float quad4_color[] =  {
6543          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6544          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6545          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6546          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6547     };
6548
6549     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6550     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6551     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6552     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6553     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6554     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6555     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6556     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6557
6558     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6559     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6560     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6561     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6562     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6563     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6564     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6565     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6566
6567     hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
6568     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6569
6570     for(i = 1; i <= 3; i++) {
6571         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6572         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6573         if(i == 3) {
6574             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6575             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6576             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6577             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6578         } else if(i == 2){
6579             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6580             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6581         } else if(i == 1) {
6582             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6583             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6584         }
6585
6586         hr = IDirect3DDevice9_BeginScene(device);
6587         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6588         if(SUCCEEDED(hr))
6589         {
6590             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6591             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6592
6593             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6594             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6595             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6596             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6597
6598             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6599             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6600             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6601             if(i == 3 || i == 2) {
6602                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6603             } else if(i == 1) {
6604                 /* Succeeds or fails, depending on SW or HW vertex processing */
6605                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6606             }
6607
6608             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6609             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6610             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6611             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6612
6613             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6614             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6615             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6616             if(i == 3 || i == 2) {
6617                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6618             } else if(i == 1) {
6619                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6620             }
6621
6622             hr = IDirect3DDevice9_EndScene(device);
6623             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6624         }
6625
6626         if(i == 3 || i == 2) {
6627             color = getPixelColor(device, 160, 360);
6628             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6629                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6630
6631             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6632             color = getPixelColor(device, 480, 360);
6633             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6634                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6635             color = getPixelColor(device, 160, 120);
6636             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6637             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6638                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6639
6640             color = getPixelColor(device, 480, 160);
6641             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6642         } else if(i == 1) {
6643             color = getPixelColor(device, 160, 360);
6644             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6645                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6646             color = getPixelColor(device, 480, 360);
6647             /* Accept the clear color as well in this case, since SW VP returns an error */
6648             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6649             color = getPixelColor(device, 160, 120);
6650             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6651                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6652             color = getPixelColor(device, 480, 160);
6653             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6654         }
6655
6656         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6657         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6658
6659         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6660         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6661
6662         /* Now find out if the whole streams are re-read, or just the last active value for the
6663          * vertices is used.
6664          */
6665         hr = IDirect3DDevice9_BeginScene(device);
6666         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6667         if(SUCCEEDED(hr))
6668         {
6669             float quad1_modified[] =  {
6670                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6671                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6672                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6673                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6674             };
6675             float quad2_modified[] =  {
6676                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6677                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6678                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6679                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6680             };
6681
6682             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6683             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6684
6685             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6686             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6687             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6688             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6689
6690             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6691             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6692             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6693             if(i == 3 || i == 2) {
6694                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6695             } else if(i == 1) {
6696                 /* Succeeds or fails, depending on SW or HW vertex processing */
6697                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6698             }
6699
6700             hr = IDirect3DDevice9_EndScene(device);
6701             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6702         }
6703
6704         color = getPixelColor(device, 480, 350);
6705         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6706          * as well.
6707          *
6708          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6709          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6710          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6711          * refrast's result.
6712          *
6713          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6714          */
6715         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6716            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6717
6718         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6719         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6720
6721         IDirect3DDevice9_SetVertexShader(device, NULL);
6722         IDirect3DDevice9_SetPixelShader(device, NULL);
6723         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6724
6725         IDirect3DVertexShader9_Release(swapped_shader);
6726     }
6727
6728     for(i = 1; i <= 3; i++) {
6729         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6730         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6731         if(i == 3) {
6732             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6733             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6734             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6735             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6736             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6737             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6738         } else if(i == 2){
6739             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6740             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6741             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6742             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6743         } else if(i == 1) {
6744             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6745             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6746             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6747             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6748         }
6749
6750         hr = IDirect3DDevice9_BeginScene(device);
6751         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6752         if(SUCCEEDED(hr))
6753         {
6754             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6755             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6756             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6757             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6758             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6759             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6760
6761             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6762             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6763
6764             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6765             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6766             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6767             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6768             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6769             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6770
6771             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6772             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6773             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6774             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6775             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6776             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6777
6778             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6779             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6780             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6781             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6782
6783             hr = IDirect3DDevice9_EndScene(device);
6784             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6785         }
6786         IDirect3DDevice9_SetVertexShader(device, NULL);
6787         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6788         IDirect3DDevice9_SetPixelShader(device, NULL);
6789
6790         color = getPixelColor(device, 160, 360);
6791         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6792            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6793         color = getPixelColor(device, 480, 360);
6794         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6795            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6796         color = getPixelColor(device, 160, 120);
6797         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6798            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6799         color = getPixelColor(device, 480, 160);
6800         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6801            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6802
6803         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6804         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6805
6806         IDirect3DVertexShader9_Release(texcoord_color_shader);
6807         IDirect3DVertexShader9_Release(color_color_shader);
6808     }
6809
6810     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6811     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6812     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6813     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6814
6815     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6816     IDirect3DVertexDeclaration9_Release(decl_color_color);
6817     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6818     IDirect3DVertexDeclaration9_Release(decl_color_float);
6819
6820     IDirect3DPixelShader9_Release(ps);
6821 }
6822
6823 static void srgbtexture_test(IDirect3DDevice9 *device)
6824 {
6825     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6826      * texture stage state to render a quad using that texture.  The resulting
6827      * color components should be 0x36 (~ 0.21), per this formula:
6828      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6829      * This is true where srgb_color > 0.04045.
6830      */
6831     IDirect3D9 *d3d = NULL;
6832     HRESULT hr;
6833     LPDIRECT3DTEXTURE9 texture = NULL;
6834     LPDIRECT3DSURFACE9 surface = NULL;
6835     D3DLOCKED_RECT lr;
6836     DWORD color;
6837     float quad[] = {
6838         -1.0,       1.0,       0.0,     0.0,    0.0,
6839          1.0,       1.0,       0.0,     1.0,    0.0,
6840         -1.0,      -1.0,       0.0,     0.0,    1.0,
6841          1.0,      -1.0,       0.0,     1.0,    1.0,
6842     };
6843
6844
6845     memset(&lr, 0, sizeof(lr));
6846     IDirect3DDevice9_GetDirect3D(device, &d3d);
6847     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6848                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6849                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6850         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6851         goto out;
6852     }
6853
6854     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6855                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6856                                         &texture, NULL);
6857     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6858     if(!texture) {
6859         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6860         goto out;
6861     }
6862     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6863     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6864
6865     fill_surface(surface, 0xff7f7f7f);
6866     IDirect3DSurface9_Release(surface);
6867
6868     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6869     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6870     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6871     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6872
6873     hr = IDirect3DDevice9_BeginScene(device);
6874     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6875     if(SUCCEEDED(hr))
6876     {
6877         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6878         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6879
6880         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6881         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6882
6883
6884         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6885         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6886
6887         hr = IDirect3DDevice9_EndScene(device);
6888         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6889     }
6890
6891     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6892     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6893     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6894     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6895
6896     color = getPixelColor(device, 320, 240);
6897     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6898
6899     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6900     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6901
6902 out:
6903     if(texture) IDirect3DTexture9_Release(texture);
6904     IDirect3D9_Release(d3d);
6905 }
6906
6907 static void shademode_test(IDirect3DDevice9 *device)
6908 {
6909     /* Render a quad and try all of the different fixed function shading models. */
6910     HRESULT hr;
6911     DWORD color0, color1;
6912     DWORD color0_gouraud = 0, color1_gouraud = 0;
6913     DWORD shademode = D3DSHADE_FLAT;
6914     DWORD primtype = D3DPT_TRIANGLESTRIP;
6915     LPVOID data = NULL;
6916     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6917     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6918     UINT i, j;
6919     struct vertex quad_strip[] =
6920     {
6921         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6922         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6923         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6924         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6925     };
6926     struct vertex quad_list[] =
6927     {
6928         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6929         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6930         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6931
6932         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6933         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6934         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6935     };
6936
6937     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6938                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6939     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6940     if (FAILED(hr)) goto bail;
6941
6942     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6943                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6944     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6945     if (FAILED(hr)) goto bail;
6946
6947     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6948     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6949
6950     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6951     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6952
6953     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6954     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6955     memcpy(data, quad_strip, sizeof(quad_strip));
6956     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6957     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6958
6959     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6960     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6961     memcpy(data, quad_list, sizeof(quad_list));
6962     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6963     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6964
6965     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6966      * the color fixups we have to do for FLAT shading will be dependent on that. */
6967     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6968     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6969
6970     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6971     for (j=0; j<2; j++) {
6972
6973         /* Inner loop just changes the D3DRS_SHADEMODE */
6974         for (i=0; i<3; i++) {
6975             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6976             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6977
6978             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6979             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6980
6981             hr = IDirect3DDevice9_BeginScene(device);
6982             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6983             if(SUCCEEDED(hr))
6984             {
6985                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6986                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6987
6988                 hr = IDirect3DDevice9_EndScene(device);
6989                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6990             }
6991
6992             /* Sample two spots from the output */
6993             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6994             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6995             switch(shademode) {
6996                 case D3DSHADE_FLAT:
6997                     /* Should take the color of the first vertex of each triangle */
6998                     if (0)
6999                     {
7000                         /* This test depends on EXT_provoking_vertex being
7001                          * available. This extension is currently (20090810)
7002                          * not common enough to let the test fail if it isn't
7003                          * present. */
7004                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
7005                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
7006                     }
7007                     shademode = D3DSHADE_GOURAUD;
7008                     break;
7009                 case D3DSHADE_GOURAUD:
7010                     /* Should be an interpolated blend */
7011
7012                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7013                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
7014                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7015                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
7016
7017                     color0_gouraud = color0;
7018                     color1_gouraud = color1;
7019
7020                     shademode = D3DSHADE_PHONG;
7021                     break;
7022                 case D3DSHADE_PHONG:
7023                     /* Should be the same as GOURAUD, since no hardware implements this */
7024                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7025                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
7026                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7027                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7028
7029                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7030                             color0_gouraud, color0);
7031                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7032                             color1_gouraud, color1);
7033                     break;
7034             }
7035         }
7036
7037         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7038         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7039
7040         /* Now, do it all over again with a TRIANGLELIST */
7041         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7042         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7043         primtype = D3DPT_TRIANGLELIST;
7044         shademode = D3DSHADE_FLAT;
7045     }
7046
7047 bail:
7048     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7049     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7050     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7051     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7052
7053     if (vb_strip)
7054         IDirect3DVertexBuffer9_Release(vb_strip);
7055     if (vb_list)
7056         IDirect3DVertexBuffer9_Release(vb_list);
7057 }
7058
7059 static void alpha_test(IDirect3DDevice9 *device)
7060 {
7061     HRESULT hr;
7062     IDirect3DTexture9 *offscreenTexture;
7063     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7064     DWORD color;
7065
7066     struct vertex quad1[] =
7067     {
7068         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
7069         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
7070         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
7071         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
7072     };
7073     struct vertex quad2[] =
7074     {
7075         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
7076         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
7077         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
7078         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
7079     };
7080     static const float composite_quad[][5] = {
7081         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7082         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
7083         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7084         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
7085     };
7086
7087     /* Clear the render target with alpha = 0.5 */
7088     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7089     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7090
7091     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7092     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7093
7094     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7095     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7096     if(!backbuffer) {
7097         goto out;
7098     }
7099
7100     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7101     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7102     if(!offscreen) {
7103         goto out;
7104     }
7105
7106     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7107     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7108
7109     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7110     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7111     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7112     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7113     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7114     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7115     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7116     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7117     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7118     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7119
7120     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7121     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7122     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7123
7124         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7125         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7126         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7127         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7128         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7129         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7130         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7131
7132         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7133         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7134         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7135         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7136         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7137         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7138
7139         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7140          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7141          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7142         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7143         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7144         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7145         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7146
7147         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7148         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7149         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7150         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7151         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7152         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7153
7154         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7155         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7156         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7157         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7158         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7159         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7160
7161         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7162         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7163
7164         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7165          * Disable alpha blending for the final composition
7166          */
7167         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7168         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7169         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7170         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7171
7172         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7173         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7174         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7175         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7176         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7177         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7178
7179         hr = IDirect3DDevice9_EndScene(device);
7180         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7181     }
7182
7183     color = getPixelColor(device, 160, 360);
7184     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7185        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7186
7187     color = getPixelColor(device, 160, 120);
7188     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7189        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7190
7191     color = getPixelColor(device, 480, 360);
7192     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7193        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7194
7195     color = getPixelColor(device, 480, 120);
7196     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7197        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7198
7199     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7200
7201     out:
7202     /* restore things */
7203     if(backbuffer) {
7204         IDirect3DSurface9_Release(backbuffer);
7205     }
7206     if(offscreenTexture) {
7207         IDirect3DTexture9_Release(offscreenTexture);
7208     }
7209     if(offscreen) {
7210         IDirect3DSurface9_Release(offscreen);
7211     }
7212 }
7213
7214 struct vertex_shortcolor {
7215     float x, y, z;
7216     unsigned short r, g, b, a;
7217 };
7218 struct vertex_floatcolor {
7219     float x, y, z;
7220     float r, g, b, a;
7221 };
7222
7223 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7224 {
7225     HRESULT hr;
7226     BOOL s_ok, ub_ok, f_ok;
7227     DWORD color, size, i;
7228     void *data;
7229     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7230         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7231         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7232         D3DDECL_END()
7233     };
7234     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7235         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7236         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7237         D3DDECL_END()
7238     };
7239     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7240         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7241         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7242         D3DDECL_END()
7243     };
7244     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7245         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7246         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7247         D3DDECL_END()
7248     };
7249     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7250         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7251         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7252         D3DDECL_END()
7253     };
7254     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7255         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7256         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7257         D3DDECL_END()
7258     };
7259     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7260         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
7261         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7262         D3DDECL_END()
7263     };
7264     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7265     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7266     IDirect3DVertexBuffer9 *vb, *vb2;
7267     struct vertex quad1[] =                             /* D3DCOLOR */
7268     {
7269         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
7270         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7271         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
7272         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7273     };
7274     struct vertex quad2[] =                             /* UBYTE4N */
7275     {
7276         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7277         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
7278         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7279         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
7280     };
7281     struct vertex_shortcolor quad3[] =                  /* short */
7282     {
7283         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7284         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7285         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7286         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7287     };
7288     struct vertex_floatcolor quad4[] =
7289     {
7290         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7291         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7292         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7293         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7294     };
7295     DWORD colors[] = {
7296         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7297         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7298         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7299         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7300         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7301         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7302         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7303         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7304         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7305         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7306         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7307         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7308         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7309         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7310         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7311         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7312     };
7313     float quads[] = {
7314         -1.0,   -1.0,     0.1,
7315         -1.0,    0.0,     0.1,
7316          0.0,   -1.0,     0.1,
7317          0.0,    0.0,     0.1,
7318
7319          0.0,   -1.0,     0.1,
7320          0.0,    0.0,     0.1,
7321          1.0,   -1.0,     0.1,
7322          1.0,    0.0,     0.1,
7323
7324          0.0,    0.0,     0.1,
7325          0.0,    1.0,     0.1,
7326          1.0,    0.0,     0.1,
7327          1.0,    1.0,     0.1,
7328
7329         -1.0,    0.0,     0.1,
7330         -1.0,    1.0,     0.1,
7331          0.0,    0.0,     0.1,
7332          0.0,    1.0,     0.1
7333     };
7334     struct tvertex quad_transformed[] = {
7335        {  90,    110,     0.1,      2.0,        0x00ffff00},
7336        { 570,    110,     0.1,      2.0,        0x00ffff00},
7337        {  90,    300,     0.1,      2.0,        0x00ffff00},
7338        { 570,    300,     0.1,      2.0,        0x00ffff00}
7339     };
7340     D3DCAPS9 caps;
7341
7342     memset(&caps, 0, sizeof(caps));
7343     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7344     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7345
7346     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7347     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7348
7349     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7350     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7351     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7352     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7353     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7354     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7355     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7356         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7357         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7358         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7359         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7360     } else {
7361         trace("D3DDTCAPS_UBYTE4N not supported\n");
7362         dcl_ubyte_2 = NULL;
7363         dcl_ubyte = NULL;
7364     }
7365     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7366     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7367     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7368     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7369
7370     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7371     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7372                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7373     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7374
7375     hr = IDirect3DDevice9_BeginScene(device);
7376     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7377     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7378     if(SUCCEEDED(hr)) {
7379         if(dcl_color) {
7380             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7381             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7382             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7383             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7384         }
7385
7386         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7387          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7388          * using software vertex processing. Doh!
7389          */
7390         if(dcl_ubyte) {
7391             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7392             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7393             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7394             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7395             ub_ok = SUCCEEDED(hr);
7396         }
7397
7398         if(dcl_short) {
7399             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7400             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7401             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7402             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7403             s_ok = SUCCEEDED(hr);
7404         }
7405
7406         if(dcl_float) {
7407             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7408             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7409             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7410             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7411             f_ok = SUCCEEDED(hr);
7412         }
7413
7414         hr = IDirect3DDevice9_EndScene(device);
7415         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7416     }
7417
7418     if(dcl_short) {
7419         color = getPixelColor(device, 480, 360);
7420         ok(color == 0x000000ff || !s_ok,
7421            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7422     }
7423     if(dcl_ubyte) {
7424         color = getPixelColor(device, 160, 120);
7425         ok(color == 0x0000ffff || !ub_ok,
7426            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7427     }
7428     if(dcl_color) {
7429         color = getPixelColor(device, 160, 360);
7430         ok(color == 0x00ffff00,
7431            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7432     }
7433     if(dcl_float) {
7434         color = getPixelColor(device, 480, 120);
7435         ok(color == 0x00ff0000 || !f_ok,
7436            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7437     }
7438     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7439
7440     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7441      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7442      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7443      * whether the immediate mode code works
7444      */
7445     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7446     hr = IDirect3DDevice9_BeginScene(device);
7447     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7448     if(SUCCEEDED(hr)) {
7449         if(dcl_color) {
7450             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7451             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7452             memcpy(data, quad1, sizeof(quad1));
7453             hr = IDirect3DVertexBuffer9_Unlock(vb);
7454             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7455             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7456             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7457             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7458             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7459             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7460             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7461         }
7462
7463         if(dcl_ubyte) {
7464             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7465             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7466             memcpy(data, quad2, sizeof(quad2));
7467             hr = IDirect3DVertexBuffer9_Unlock(vb);
7468             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7469             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7470             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7471             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7472             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7473             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7474             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7475                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7476             ub_ok = SUCCEEDED(hr);
7477         }
7478
7479         if(dcl_short) {
7480             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7481             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7482             memcpy(data, quad3, sizeof(quad3));
7483             hr = IDirect3DVertexBuffer9_Unlock(vb);
7484             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7485             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7486             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7487             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7488             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7489             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7490             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7491                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7492             s_ok = SUCCEEDED(hr);
7493         }
7494
7495         if(dcl_float) {
7496             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7497             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7498             memcpy(data, quad4, sizeof(quad4));
7499             hr = IDirect3DVertexBuffer9_Unlock(vb);
7500             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7501             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7502             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7503             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7504             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7505             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7506             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7507                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7508             f_ok = SUCCEEDED(hr);
7509         }
7510
7511         hr = IDirect3DDevice9_EndScene(device);
7512         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7513     }
7514
7515     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7516     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7517     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7518     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7519
7520     if(dcl_short) {
7521         color = getPixelColor(device, 480, 360);
7522         ok(color == 0x000000ff || !s_ok,
7523            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7524     }
7525     if(dcl_ubyte) {
7526         color = getPixelColor(device, 160, 120);
7527         ok(color == 0x0000ffff || !ub_ok,
7528            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7529     }
7530     if(dcl_color) {
7531         color = getPixelColor(device, 160, 360);
7532         ok(color == 0x00ffff00,
7533            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7534     }
7535     if(dcl_float) {
7536         color = getPixelColor(device, 480, 120);
7537         ok(color == 0x00ff0000 || !f_ok,
7538            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7539     }
7540     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7541
7542     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7543     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7544
7545     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7546     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7547     memcpy(data, quad_transformed, sizeof(quad_transformed));
7548     hr = IDirect3DVertexBuffer9_Unlock(vb);
7549     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7550
7551     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7552     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7553
7554     hr = IDirect3DDevice9_BeginScene(device);
7555     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7556     if(SUCCEEDED(hr)) {
7557         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7558         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7559         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7560         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7561
7562         hr = IDirect3DDevice9_EndScene(device);
7563         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7564     }
7565
7566     color = getPixelColor(device, 88, 108);
7567     ok(color == 0x000000ff,
7568        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7569     color = getPixelColor(device, 92, 108);
7570     ok(color == 0x000000ff,
7571        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7572     color = getPixelColor(device, 88, 112);
7573     ok(color == 0x000000ff,
7574        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7575     color = getPixelColor(device, 92, 112);
7576     ok(color == 0x00ffff00,
7577        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7578
7579     color = getPixelColor(device, 568, 108);
7580     ok(color == 0x000000ff,
7581        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7582     color = getPixelColor(device, 572, 108);
7583     ok(color == 0x000000ff,
7584        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7585     color = getPixelColor(device, 568, 112);
7586     ok(color == 0x00ffff00,
7587        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7588     color = getPixelColor(device, 572, 112);
7589     ok(color == 0x000000ff,
7590        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7591
7592     color = getPixelColor(device, 88, 298);
7593     ok(color == 0x000000ff,
7594        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7595     color = getPixelColor(device, 92, 298);
7596     ok(color == 0x00ffff00,
7597        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7598     color = getPixelColor(device, 88, 302);
7599     ok(color == 0x000000ff,
7600        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7601     color = getPixelColor(device, 92, 302);
7602     ok(color == 0x000000ff,
7603        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7604
7605     color = getPixelColor(device, 568, 298);
7606     ok(color == 0x00ffff00,
7607        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7608     color = getPixelColor(device, 572, 298);
7609     ok(color == 0x000000ff,
7610        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7611     color = getPixelColor(device, 568, 302);
7612     ok(color == 0x000000ff,
7613        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7614     color = getPixelColor(device, 572, 302);
7615     ok(color == 0x000000ff,
7616        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7617
7618     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7619
7620     /* This test is pointless without those two declarations: */
7621     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7622         skip("color-ubyte switching test declarations aren't supported\n");
7623         goto out;
7624     }
7625
7626     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7627     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7628     memcpy(data, quads, sizeof(quads));
7629     hr = IDirect3DVertexBuffer9_Unlock(vb);
7630     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7631     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7632                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7633     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7634     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7635     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7636     memcpy(data, colors, sizeof(colors));
7637     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7638     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7639
7640     for(i = 0; i < 2; i++) {
7641         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7642         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7643
7644         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7645         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7646         if(i == 0) {
7647             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7648         } else {
7649             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7650         }
7651         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7652
7653         hr = IDirect3DDevice9_BeginScene(device);
7654         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7655         ub_ok = FALSE;
7656         if(SUCCEEDED(hr)) {
7657             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7658             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7659             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7660             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7661                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7662             ub_ok = SUCCEEDED(hr);
7663
7664             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7665             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7666             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7667             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7668
7669             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7670             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7671             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7672             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7673                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7674             ub_ok = (SUCCEEDED(hr) && ub_ok);
7675
7676             hr = IDirect3DDevice9_EndScene(device);
7677             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7678         }
7679
7680         if(i == 0) {
7681             color = getPixelColor(device, 480, 360);
7682             ok(color == 0x00ff0000,
7683                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7684             color = getPixelColor(device, 160, 120);
7685             ok(color == 0x00ffffff,
7686                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7687             color = getPixelColor(device, 160, 360);
7688             ok(color == 0x000000ff || !ub_ok,
7689                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7690             color = getPixelColor(device, 480, 120);
7691             ok(color == 0x000000ff || !ub_ok,
7692                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7693         } else {
7694             color = getPixelColor(device, 480, 360);
7695             ok(color == 0x000000ff,
7696                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7697             color = getPixelColor(device, 160, 120);
7698             ok(color == 0x00ffffff,
7699                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7700             color = getPixelColor(device, 160, 360);
7701             ok(color == 0x00ff0000 || !ub_ok,
7702                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7703             color = getPixelColor(device, 480, 120);
7704             ok(color == 0x00ff0000 || !ub_ok,
7705                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7706         }
7707         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7708     }
7709
7710     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7711     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7712     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7713     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7714     IDirect3DVertexBuffer9_Release(vb2);
7715
7716     out:
7717     IDirect3DVertexBuffer9_Release(vb);
7718     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7719     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7720     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7721     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7722     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7723     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7724     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7725 }
7726
7727 struct vertex_float16color {
7728     float x, y, z;
7729     DWORD c1, c2;
7730 };
7731
7732 static void test_vshader_float16(IDirect3DDevice9 *device)
7733 {
7734     HRESULT hr;
7735     DWORD color;
7736     void *data;
7737     static const D3DVERTEXELEMENT9 decl_elements[] = {
7738         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7739         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7740         D3DDECL_END()
7741     };
7742     IDirect3DVertexDeclaration9 *vdecl = NULL;
7743     IDirect3DVertexBuffer9 *buffer = NULL;
7744     IDirect3DVertexShader9 *shader;
7745     DWORD shader_code[] = {
7746         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7747         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7748         0x90e40001, 0x0000ffff
7749     };
7750     struct vertex_float16color quad[] = {
7751         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7752         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7753         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7754         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7755
7756         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7757         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7758         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7759         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7760
7761         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7762         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7763         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7764         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7765
7766         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7767         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7768         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7769         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7770     };
7771
7772     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7773     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7774
7775     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7776     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7777     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7778     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7779     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7780     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7781
7782     hr = IDirect3DDevice9_BeginScene(device);
7783     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7784     if(SUCCEEDED(hr)) {
7785         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7786         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7787         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7788         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7789         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7790         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7791         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7792         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7793         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7794         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7795
7796         hr = IDirect3DDevice9_EndScene(device);
7797         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7798     }
7799     color = getPixelColor(device, 480, 360);
7800     ok(color == 0x00ff0000,
7801        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7802     color = getPixelColor(device, 160, 120);
7803     ok(color == 0x00000000,
7804        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7805     color = getPixelColor(device, 160, 360);
7806     ok(color == 0x0000ff00,
7807        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7808     color = getPixelColor(device, 480, 120);
7809     ok(color == 0x000000ff,
7810        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7811     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7812
7813     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7814     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7815
7816     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7817                                              D3DPOOL_MANAGED, &buffer, NULL);
7818     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7819     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7820     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7821     memcpy(data, quad, sizeof(quad));
7822     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7823     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7824     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7825     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7826
7827     hr = IDirect3DDevice9_BeginScene(device);
7828     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7829     if(SUCCEEDED(hr)) {
7830             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7831             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7832             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7833             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7834             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7835             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7836             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7837             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7838
7839             hr = IDirect3DDevice9_EndScene(device);
7840             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7841     }
7842
7843     color = getPixelColor(device, 480, 360);
7844     ok(color == 0x00ff0000,
7845        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7846     color = getPixelColor(device, 160, 120);
7847     ok(color == 0x00000000,
7848        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7849     color = getPixelColor(device, 160, 360);
7850     ok(color == 0x0000ff00,
7851        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7852     color = getPixelColor(device, 480, 120);
7853     ok(color == 0x000000ff,
7854        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7855     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7856
7857     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7858     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7859     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7860     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7861     IDirect3DDevice9_SetVertexShader(device, NULL);
7862     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7863
7864     IDirect3DVertexDeclaration9_Release(vdecl);
7865     IDirect3DVertexShader9_Release(shader);
7866     IDirect3DVertexBuffer9_Release(buffer);
7867 }
7868
7869 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7870 {
7871     D3DCAPS9 caps;
7872     IDirect3DTexture9 *texture;
7873     HRESULT hr;
7874     D3DLOCKED_RECT rect;
7875     unsigned int x, y;
7876     DWORD *dst, color;
7877     const float quad[] = {
7878         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7879          1.0,   -1.0,   0.1,    1.2,   -0.2,
7880         -1.0,    1.0,   0.1,   -0.2,    1.2,
7881          1.0,    1.0,   0.1,    1.2,    1.2
7882     };
7883     memset(&caps, 0, sizeof(caps));
7884
7885     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7886     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7887     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7888         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7889         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7890            "Card has conditional NP2 support without power of two restriction set\n");
7891         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7892         return;
7893     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7894         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7895         return;
7896     }
7897
7898     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7899     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7900
7901     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7902     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7903
7904     memset(&rect, 0, sizeof(rect));
7905     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7906     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7907     for(y = 0; y < 10; y++) {
7908         for(x = 0; x < 10; x++) {
7909             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7910             if(x == 0 || x == 9 || y == 0 || y == 9) {
7911                 *dst = 0x00ff0000;
7912             } else {
7913                 *dst = 0x000000ff;
7914             }
7915         }
7916     }
7917     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7918     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7919
7920     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7921     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7922     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7923     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7924     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7925     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7926     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7927     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7928
7929     hr = IDirect3DDevice9_BeginScene(device);
7930     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7931     if(SUCCEEDED(hr)) {
7932         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7933         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7934
7935         hr = IDirect3DDevice9_EndScene(device);
7936         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7937     }
7938
7939     color = getPixelColor(device,    1,  1);
7940     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7941     color = getPixelColor(device, 639, 479);
7942     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7943
7944     color = getPixelColor(device, 135, 101);
7945     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7946     color = getPixelColor(device, 140, 101);
7947     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7948     color = getPixelColor(device, 135, 105);
7949     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7950     color = getPixelColor(device, 140, 105);
7951     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7952
7953     color = getPixelColor(device, 135, 376);
7954     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7955     color = getPixelColor(device, 140, 376);
7956     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7957     color = getPixelColor(device, 135, 379);
7958     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7959     color = getPixelColor(device, 140, 379);
7960     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7961
7962     color = getPixelColor(device, 500, 101);
7963     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7964     color = getPixelColor(device, 504, 101);
7965     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7966     color = getPixelColor(device, 500, 105);
7967     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7968     color = getPixelColor(device, 504, 105);
7969     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7970
7971     color = getPixelColor(device, 500, 376);
7972     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7973     color = getPixelColor(device, 504, 376);
7974     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7975     color = getPixelColor(device, 500, 380);
7976     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7977     color = getPixelColor(device, 504, 380);
7978     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7979
7980     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7981
7982     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7983     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7984     IDirect3DTexture9_Release(texture);
7985 }
7986
7987 static void vFace_register_test(IDirect3DDevice9 *device)
7988 {
7989     HRESULT hr;
7990     DWORD color;
7991     const DWORD shader_code[] = {
7992         0xffff0300,                                                             /* ps_3_0                     */
7993         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7994         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7995         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7996         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7997         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7998         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7999         0x0000ffff                                                              /* END                        */
8000     };
8001     const DWORD vshader_code[] = {
8002         0xfffe0300,                                                             /* vs_3_0               */
8003         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8004         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8005         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8006         0x0000ffff                                                              /* end                  */
8007     };
8008     IDirect3DPixelShader9 *shader;
8009     IDirect3DVertexShader9 *vshader;
8010     IDirect3DTexture9 *texture;
8011     IDirect3DSurface9 *surface, *backbuffer;
8012     const float quad[] = {
8013         -1.0,   -1.0,   0.1,
8014          1.0,   -1.0,   0.1,
8015         -1.0,    0.0,   0.1,
8016
8017          1.0,   -1.0,   0.1,
8018          1.0,    0.0,   0.1,
8019         -1.0,    0.0,   0.1,
8020
8021         -1.0,    0.0,   0.1,
8022         -1.0,    1.0,   0.1,
8023          1.0,    0.0,   0.1,
8024
8025          1.0,    0.0,   0.1,
8026         -1.0,    1.0,   0.1,
8027          1.0,    1.0,   0.1,
8028     };
8029     const float blit[] = {
8030          0.0,   -1.0,   0.1,    0.0,    0.0,
8031          1.0,   -1.0,   0.1,    1.0,    0.0,
8032          0.0,    1.0,   0.1,    0.0,    1.0,
8033          1.0,    1.0,   0.1,    1.0,    1.0,
8034     };
8035
8036     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8037     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8038     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8039     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8040     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8041     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8042     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8043     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8044     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8045     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8046     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8047     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8048     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8049     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8050     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8051     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8052
8053     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8054     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8055
8056     hr = IDirect3DDevice9_BeginScene(device);
8057     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8058     if(SUCCEEDED(hr)) {
8059         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8060         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8061         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8062         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8063         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8064         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8065         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8066         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8067         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8068         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8069         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8070
8071         /* Blit the texture onto the back buffer to make it visible */
8072         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8073         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
8074         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8075         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8076         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8077         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8078         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8079         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8080         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8081         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8082         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8083         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8084
8085         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8086         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8087
8088         hr = IDirect3DDevice9_EndScene(device);
8089         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8090     }
8091
8092     color = getPixelColor(device, 160, 360);
8093     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8094     color = getPixelColor(device, 160, 120);
8095     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8096     color = getPixelColor(device, 480, 360);
8097     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8098     color = getPixelColor(device, 480, 120);
8099     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8100     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8101
8102     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8103     IDirect3DDevice9_SetTexture(device, 0, NULL);
8104     IDirect3DPixelShader9_Release(shader);
8105     IDirect3DVertexShader9_Release(vshader);
8106     IDirect3DSurface9_Release(surface);
8107     IDirect3DSurface9_Release(backbuffer);
8108     IDirect3DTexture9_Release(texture);
8109 }
8110
8111 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8112 {
8113     HRESULT hr;
8114     DWORD color;
8115     int i;
8116     D3DCAPS9 caps;
8117     BOOL L6V5U5_supported = FALSE;
8118     IDirect3DTexture9 *tex1, *tex2;
8119     D3DLOCKED_RECT locked_rect;
8120
8121     static const float quad[][7] = {
8122         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8123         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8124         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8125         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8126     };
8127
8128     static const D3DVERTEXELEMENT9 decl_elements[] = {
8129         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8130         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8131         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8132         D3DDECL_END()
8133     };
8134
8135     /* use asymmetric matrix to test loading */
8136     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8137     float scale, offset;
8138
8139     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8140     IDirect3DTexture9           *texture            = NULL;
8141
8142     memset(&caps, 0, sizeof(caps));
8143     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8144     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8145     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8146         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8147         return;
8148     } else {
8149         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8150          * They report that it is not supported, but after that bump mapping works properly. So just test
8151          * if the format is generally supported, and check the BUMPENVMAP flag
8152          */
8153         IDirect3D9 *d3d9;
8154
8155         IDirect3DDevice9_GetDirect3D(device, &d3d9);
8156         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8157                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8158         L6V5U5_supported = SUCCEEDED(hr);
8159         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8160                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8161         IDirect3D9_Release(d3d9);
8162         if(FAILED(hr)) {
8163             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8164             return;
8165         }
8166     }
8167
8168     /* Generate the textures */
8169     generate_bumpmap_textures(device);
8170
8171     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8172     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8173     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8174     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8175     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8176     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8177     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8178     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8179
8180     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8181     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8182     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8183     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8184     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8185     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8186
8187     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8188     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8189     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8190     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8191     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8192     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8193
8194     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8195     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8196
8197     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8198     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8199
8200     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8201     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8202
8203
8204     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8205     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8206     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8207     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8208
8209     hr = IDirect3DDevice9_BeginScene(device);
8210     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8211
8212     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8213     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8214
8215     hr = IDirect3DDevice9_EndScene(device);
8216     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8217
8218     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8219      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8220      * But since testing the color match is not the purpose of the test don't be too picky
8221      */
8222     color = getPixelColor(device, 320-32, 240);
8223     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8224     color = getPixelColor(device, 320+32, 240);
8225     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8226     color = getPixelColor(device, 320, 240-32);
8227     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8228     color = getPixelColor(device, 320, 240+32);
8229     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8230     color = getPixelColor(device, 320, 240);
8231     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8232     color = getPixelColor(device, 320+32, 240+32);
8233     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8234     color = getPixelColor(device, 320-32, 240+32);
8235     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8236     color = getPixelColor(device, 320+32, 240-32);
8237     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8238     color = getPixelColor(device, 320-32, 240-32);
8239     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8240     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8241     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8242
8243     for(i = 0; i < 2; i++) {
8244         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8245         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8246         IDirect3DTexture9_Release(texture); /* For the GetTexture */
8247         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8248         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8249         IDirect3DTexture9_Release(texture); /* To destroy it */
8250     }
8251
8252     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8253         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8254         goto cleanup;
8255     }
8256     if(L6V5U5_supported == FALSE) {
8257         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8258         goto cleanup;
8259     }
8260
8261     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8262     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8263     /* This test only tests the luminance part. The bumpmapping part was already tested above and
8264      * would only make this test more complicated
8265      */
8266     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8267     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8268     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8269     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8270
8271     memset(&locked_rect, 0, sizeof(locked_rect));
8272     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8273     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8274     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8275     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8276     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8277
8278     memset(&locked_rect, 0, sizeof(locked_rect));
8279     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8280     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8281     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8282     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8283     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8284
8285     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8286     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8287     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8288     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8289
8290     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8291     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8292     scale = 2.0;
8293     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8294     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8295     offset = 0.1;
8296     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8297     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8298
8299     hr = IDirect3DDevice9_BeginScene(device);
8300     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8301     if(SUCCEEDED(hr)) {
8302         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8303         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8304         hr = IDirect3DDevice9_EndScene(device);
8305         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8306     }
8307
8308     color = getPixelColor(device, 320, 240);
8309     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
8310      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
8311      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8312      */
8313     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8314     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8315     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8316
8317     /* Check a result scale factor > 1.0 */
8318     scale = 10;
8319     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8320     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8321     offset = 10;
8322     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8323     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8324
8325     hr = IDirect3DDevice9_BeginScene(device);
8326     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8327     if(SUCCEEDED(hr)) {
8328         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8329         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8330         hr = IDirect3DDevice9_EndScene(device);
8331         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8332     }
8333     color = getPixelColor(device, 320, 240);
8334     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8335     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8336     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8337
8338     /* Check clamping in the scale factor calculation */
8339     scale = 1000;
8340     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8341     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8342     offset = -1;
8343     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8344     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8345
8346     hr = IDirect3DDevice9_BeginScene(device);
8347     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8348     if(SUCCEEDED(hr)) {
8349         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8350         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8351         hr = IDirect3DDevice9_EndScene(device);
8352         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8353     }
8354     color = getPixelColor(device, 320, 240);
8355     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8356     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8357     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8358
8359     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8360     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8361     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8362     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8363
8364     IDirect3DTexture9_Release(tex1);
8365     IDirect3DTexture9_Release(tex2);
8366
8367 cleanup:
8368     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8369     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8370     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8371     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8372
8373     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8374     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8375     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8376 }
8377
8378 static void stencil_cull_test(IDirect3DDevice9 *device) {
8379     HRESULT hr;
8380     IDirect3DSurface9 *depthstencil = NULL;
8381     D3DSURFACE_DESC desc;
8382     float quad1[] = {
8383         -1.0,   -1.0,   0.1,
8384          0.0,   -1.0,   0.1,
8385         -1.0,    0.0,   0.1,
8386          0.0,    0.0,   0.1,
8387     };
8388     float quad2[] = {
8389          0.0,   -1.0,   0.1,
8390          1.0,   -1.0,   0.1,
8391          0.0,    0.0,   0.1,
8392          1.0,    0.0,   0.1,
8393     };
8394     float quad3[] = {
8395         0.0,    0.0,   0.1,
8396         1.0,    0.0,   0.1,
8397         0.0,    1.0,   0.1,
8398         1.0,    1.0,   0.1,
8399     };
8400     float quad4[] = {
8401         -1.0,    0.0,   0.1,
8402          0.0,    0.0,   0.1,
8403         -1.0,    1.0,   0.1,
8404          0.0,    1.0,   0.1,
8405     };
8406     struct vertex painter[] = {
8407        {-1.0,   -1.0,   0.0,    0x00000000},
8408        { 1.0,   -1.0,   0.0,    0x00000000},
8409        {-1.0,    1.0,   0.0,    0x00000000},
8410        { 1.0,    1.0,   0.0,    0x00000000},
8411     };
8412     WORD indices_cw[]  = {0, 1, 3};
8413     WORD indices_ccw[] = {0, 2, 3};
8414     unsigned int i;
8415     DWORD color;
8416
8417     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8418     if(depthstencil == NULL) {
8419         skip("No depth stencil buffer\n");
8420         return;
8421     }
8422     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8423     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8424     IDirect3DSurface9_Release(depthstencil);
8425     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8426         skip("No 4 or 8 bit stencil surface\n");
8427         return;
8428     }
8429
8430     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8431     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8432     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8433
8434     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8435     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8436     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8437     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8438     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8439     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8440     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8441     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8442
8443     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8444     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8445     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8446     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8447     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8448     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8449
8450     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8451     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8452     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8453     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8454
8455     /* First pass: Fill the stencil buffer with some values... */
8456     hr = IDirect3DDevice9_BeginScene(device);
8457     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8458     if(SUCCEEDED(hr))
8459     {
8460         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8461         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8462         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8463                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8464         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8465         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8466                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8467         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8468
8469         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8470         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8471         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8472         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8473         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8474                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8475         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8476         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8477                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8478         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8479
8480         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8481         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8482         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8483                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8484         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8485         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8486                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8487         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8488
8489         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8490         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8491         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8492                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8493         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8494         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8495                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8496         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8497
8498         hr = IDirect3DDevice9_EndScene(device);
8499         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8500     }
8501
8502     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8503     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8504     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8505     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8506     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8507     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8508     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8509     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8510     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8511     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8512     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8513     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8514     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8515
8516     /* 2nd pass: Make the stencil values visible */
8517     hr = IDirect3DDevice9_BeginScene(device);
8518     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8519     if(SUCCEEDED(hr))
8520     {
8521         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8522         for(i = 0; i < 16; i++) {
8523             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8524             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8525
8526             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8527             painter[1].diffuse = (i * 16);
8528             painter[2].diffuse = (i * 16);
8529             painter[3].diffuse = (i * 16);
8530             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8531             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8532         }
8533         hr = IDirect3DDevice9_EndScene(device);
8534         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8535     }
8536
8537     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8538     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8539
8540     color = getPixelColor(device, 160, 420);
8541     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8542     color = getPixelColor(device, 160, 300);
8543     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8544
8545     color = getPixelColor(device, 480, 420);
8546     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8547     color = getPixelColor(device, 480, 300);
8548     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8549
8550     color = getPixelColor(device, 160, 180);
8551     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8552     color = getPixelColor(device, 160, 60);
8553     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8554
8555     color = getPixelColor(device, 480, 180);
8556     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8557     color = getPixelColor(device, 480, 60);
8558     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8559
8560     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8561     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8562 }
8563
8564 static void vpos_register_test(IDirect3DDevice9 *device)
8565 {
8566     HRESULT hr;
8567     DWORD color;
8568     const DWORD shader_code[] = {
8569     0xffff0300,                                                             /* ps_3_0                     */
8570     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8571     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8572     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8573     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8574     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8575     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8576     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8577     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8578     0x0000ffff                                                              /* end                        */
8579     };
8580     const DWORD shader_frac_code[] = {
8581     0xffff0300,                                                             /* ps_3_0                     */
8582     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8583     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8584     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8585     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8586     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8587     0x0000ffff                                                              /* end                        */
8588     };
8589     const DWORD vshader_code[] = {
8590         0xfffe0300,                                                             /* vs_3_0               */
8591         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8592         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8593         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8594         0x0000ffff                                                              /* end                  */
8595     };
8596     IDirect3DVertexShader9 *vshader;
8597     IDirect3DPixelShader9 *shader, *shader_frac;
8598     IDirect3DSurface9 *surface = NULL, *backbuffer;
8599     const float quad[] = {
8600         -1.0,   -1.0,   0.1,    0.0,    0.0,
8601          1.0,   -1.0,   0.1,    1.0,    0.0,
8602         -1.0,    1.0,   0.1,    0.0,    1.0,
8603          1.0,    1.0,   0.1,    1.0,    1.0,
8604     };
8605     D3DLOCKED_RECT lr;
8606     float constant[4] = {1.0, 0.0, 320, 240};
8607     DWORD *pos;
8608
8609     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8610     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8611     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8612     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8613     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8614     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8615     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8616     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8617     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8618     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8619     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8620     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8621     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8622     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8623     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8624     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8625
8626     hr = IDirect3DDevice9_BeginScene(device);
8627     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8628     if(SUCCEEDED(hr)) {
8629         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8630         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8631         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8632         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8633         hr = IDirect3DDevice9_EndScene(device);
8634         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8635     }
8636
8637     /* This has to be pixel exact */
8638     color = getPixelColor(device, 319, 239);
8639     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8640     color = getPixelColor(device, 320, 239);
8641     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8642     color = getPixelColor(device, 319, 240);
8643     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8644     color = getPixelColor(device, 320, 240);
8645     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8646     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8647
8648     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8649                                              &surface, NULL);
8650     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8651     hr = IDirect3DDevice9_BeginScene(device);
8652     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8653     if(SUCCEEDED(hr)) {
8654         constant[2] = 16; constant[3] = 16;
8655         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8656         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8657         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8658         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8659         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8660         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8661         hr = IDirect3DDevice9_EndScene(device);
8662         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8663     }
8664     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8665     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8666
8667     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8668     color = *pos & 0x00ffffff;
8669     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8670     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8671     color = *pos & 0x00ffffff;
8672     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8673     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8674     color = *pos & 0x00ffffff;
8675     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8676     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8677     color = *pos & 0x00ffffff;
8678     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8679
8680     hr = IDirect3DSurface9_UnlockRect(surface);
8681     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8682
8683     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8684      * have full control over the multisampling setting inside this test
8685      */
8686     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8687     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8688     hr = IDirect3DDevice9_BeginScene(device);
8689     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8690     if(SUCCEEDED(hr)) {
8691         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8692         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8693         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8694         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8695         hr = IDirect3DDevice9_EndScene(device);
8696         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8697     }
8698     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8699     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8700
8701     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8702     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8703
8704     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8705     color = *pos & 0x00ffffff;
8706     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8707
8708     hr = IDirect3DSurface9_UnlockRect(surface);
8709     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8710
8711     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8712     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8713     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8714     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8715     IDirect3DPixelShader9_Release(shader);
8716     IDirect3DPixelShader9_Release(shader_frac);
8717     IDirect3DVertexShader9_Release(vshader);
8718     if(surface) IDirect3DSurface9_Release(surface);
8719     IDirect3DSurface9_Release(backbuffer);
8720 }
8721
8722 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8723 {
8724     D3DCOLOR color;
8725
8726     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8727     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8728     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8729     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8730     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8731
8732     ++r;
8733     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8734     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8735     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8736     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8737     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8738
8739     return TRUE;
8740 }
8741
8742 static void pointsize_test(IDirect3DDevice9 *device)
8743 {
8744     HRESULT hr;
8745     D3DCAPS9 caps;
8746     D3DMATRIX matrix;
8747     D3DMATRIX identity;
8748     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8749     DWORD color;
8750     IDirect3DSurface9 *rt, *backbuffer;
8751     IDirect3DTexture9 *tex1, *tex2;
8752     RECT rect = {0, 0, 128, 128};
8753     D3DLOCKED_RECT lr;
8754     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8755                                 0x00000000, 0x00000000};
8756     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8757                                 0x00000000, 0x0000ff00};
8758
8759     const float vertices[] = {
8760         64,     64,     0.1,
8761         128,    64,     0.1,
8762         192,    64,     0.1,
8763         256,    64,     0.1,
8764         320,    64,     0.1,
8765         384,    64,     0.1,
8766         448,    64,     0.1,
8767         512,    64,     0.1,
8768     };
8769
8770     /* 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 */
8771     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;
8772     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;
8773     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;
8774     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;
8775
8776     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;
8777     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;
8778     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;
8779     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;
8780
8781     memset(&caps, 0, sizeof(caps));
8782     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8783     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8784     if(caps.MaxPointSize < 32.0) {
8785         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8786         return;
8787     }
8788
8789     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8790     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8791     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8792     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8793     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8794     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8795     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8796     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8797
8798     hr = IDirect3DDevice9_BeginScene(device);
8799     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8800     if (SUCCEEDED(hr))
8801     {
8802         ptsize = 15.0;
8803         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8804         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8805         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8806         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8807
8808         ptsize = 31.0;
8809         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8810         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8811         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8812         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8813
8814         ptsize = 30.75;
8815         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8816         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8817         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8818         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8819
8820         if (caps.MaxPointSize >= 63.0)
8821         {
8822             ptsize = 63.0;
8823             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8824             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8825             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8826             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8827
8828             ptsize = 62.75;
8829             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8830             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8831             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8832             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8833         }
8834
8835         ptsize = 1.0;
8836         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8837         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8838         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8839         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8840
8841         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8842         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8843         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8844         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8845
8846         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8847         ptsize = 15.0;
8848         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8849         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8850         ptsize = 1.0;
8851         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8852         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8853         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8854         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8855
8856         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8857         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8858
8859         /* pointsize < pointsize_min < pointsize_max?
8860          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8861         ptsize = 1.0;
8862         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8863         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8864         ptsize = 15.0;
8865         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8866         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8867         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8868         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8869
8870         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8871         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8872
8873         hr = IDirect3DDevice9_EndScene(device);
8874         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8875     }
8876
8877     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8878     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8879     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8880
8881     if (caps.MaxPointSize >= 63.0)
8882     {
8883         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8884         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8885     }
8886
8887     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8888     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8889     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8890     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8891     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8892
8893     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8894
8895     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8896      * generates texture coordinates for the point(result: Yes, it does)
8897      *
8898      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8899      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8900      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8901      */
8902     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8903     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8904
8905     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8906     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8907     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8908     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8909     memset(&lr, 0, sizeof(lr));
8910     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8911     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8912     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8913     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8914     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8915     memset(&lr, 0, sizeof(lr));
8916     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8917     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8918     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8919     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8920     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8921     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8922     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8923     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8924     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8925     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8926     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8927     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8928     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8929     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8930     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8931     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8932     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8933     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8934     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8935
8936     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8937     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8938     ptsize = 32.0;
8939     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8940     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8941
8942     hr = IDirect3DDevice9_BeginScene(device);
8943     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8944     if(SUCCEEDED(hr))
8945     {
8946         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8947         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8948         hr = IDirect3DDevice9_EndScene(device);
8949         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8950     }
8951
8952     color = getPixelColor(device, 64-4, 64-4);
8953     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8954     color = getPixelColor(device, 64-4, 64+4);
8955     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8956     color = getPixelColor(device, 64+4, 64+4);
8957     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8958     color = getPixelColor(device, 64+4, 64-4);
8959     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8960     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8961
8962     U(matrix).m[0][0] =  1.0f / 64.0f;
8963     U(matrix).m[1][1] = -1.0f / 64.0f;
8964     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8965     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8966
8967     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8968     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8969
8970     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8971             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8972     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8973
8974     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8975     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8976     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
8977     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
8978
8979     hr = IDirect3DDevice9_BeginScene(device);
8980     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8981     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8982     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8983     hr = IDirect3DDevice9_EndScene(device);
8984     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8985
8986     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
8987     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
8988     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8989     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8990     IDirect3DSurface9_Release(backbuffer);
8991     IDirect3DSurface9_Release(rt);
8992
8993     color = getPixelColor(device, 64-4, 64-4);
8994     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
8995             "Expected color 0x00ff0000, got 0x%08x.\n", color);
8996     color = getPixelColor(device, 64+4, 64-4);
8997     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
8998             "Expected color 0x00ffff00, got 0x%08x.\n", color);
8999     color = getPixelColor(device, 64-4, 64+4);
9000     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
9001             "Expected color 0x00000000, got 0x%08x.\n", color);
9002     color = getPixelColor(device, 64+4, 64+4);
9003     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9004             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9005
9006     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9007     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9008
9009     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9010     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9011     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9012     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9013     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9014     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9015     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9016     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9017     IDirect3DTexture9_Release(tex1);
9018     IDirect3DTexture9_Release(tex2);
9019
9020     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9021     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9022     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9023     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9024     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9025     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9026 }
9027
9028 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9029 {
9030     static const DWORD vshader_code[] =
9031     {
9032         0xfffe0300,                                                             /* vs_3_0                     */
9033         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0            */
9034         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0            */
9035         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                 */
9036         0x0000ffff                                                              /* end                        */
9037     };
9038     static const DWORD pshader_code1[] =
9039     {
9040         0xffff0300,                                                             /* ps_3_0                     */
9041         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9042         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
9043         0x0000ffff                                                              /* end                        */
9044     };
9045     static const DWORD pshader_code2[] =
9046     {
9047         0xffff0300,                                                             /* ps_3_0                     */
9048         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9049         0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
9050         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
9051         0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1                */
9052         0x0000ffff                                                              /* end                        */
9053     };
9054
9055     HRESULT hr;
9056     IDirect3DVertexShader9 *vs;
9057     IDirect3DPixelShader9 *ps1, *ps2;
9058     IDirect3DTexture9 *tex1, *tex2;
9059     IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
9060     D3DCAPS9 caps;
9061     DWORD color;
9062     UINT i, j;
9063     float quad[] = {
9064        -1.0,   -1.0,    0.1,
9065         1.0,   -1.0,    0.1,
9066        -1.0,    1.0,    0.1,
9067         1.0,    1.0,    0.1,
9068     };
9069     float texquad[] = {
9070        -1.0,   -1.0,    0.1,    0.0,    0.0,
9071         0.0,   -1.0,    0.1,    1.0,    0.0,
9072        -1.0,    1.0,    0.1,    0.0,    1.0,
9073         0.0,    1.0,    0.1,    1.0,    1.0,
9074
9075         0.0,   -1.0,    0.1,    0.0,    0.0,
9076         1.0,   -1.0,    0.1,    1.0,    0.0,
9077         0.0,    1.0,    0.1,    0.0,    1.0,
9078         1.0,    1.0,    0.1,    1.0,    1.0,
9079     };
9080
9081     memset(&caps, 0, sizeof(caps));
9082     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9083     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9084     if(caps.NumSimultaneousRTs < 2) {
9085         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9086         return;
9087     }
9088
9089     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9090     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9091
9092     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
9093             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
9094     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
9095
9096     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9097             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9098     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9099     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9100             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9101     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9102     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
9103     ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
9104     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
9105     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9106     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
9107     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
9108
9109     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9110     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9111     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9112     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9113     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9114     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9115
9116     hr = IDirect3DDevice9_SetVertexShader(device, vs);
9117     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9118     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9119     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9120     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9121     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9122     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9123     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9124
9125     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
9126     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9127     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9128     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9129     color = getPixelColorFromSurface(readback, 8, 8);
9130     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9131             "Expected color 0x000000ff, got 0x%08x.\n", color);
9132     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9133     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9134     color = getPixelColorFromSurface(readback, 8, 8);
9135     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9136             "Expected color 0x000000ff, got 0x%08x.\n", color);
9137
9138     /* Render targets not written by the pixel shader should be unmodified. */
9139     hr = IDirect3DDevice9_SetPixelShader(device, ps1);
9140     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9141     hr = IDirect3DDevice9_BeginScene(device);
9142     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9143     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9144     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9145     hr = IDirect3DDevice9_EndScene(device);
9146     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9147     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9148     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9149     color = getPixelColorFromSurface(readback, 8, 8);
9150     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9151             "Expected color 0xff00ff00, got 0x%08x.\n", color);
9152     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9153     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9154     for (i = 6; i < 10; ++i)
9155     {
9156         for (j = 6; j < 10; ++j)
9157         {
9158             color = getPixelColorFromSurface(readback, j, i);
9159             ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
9160                     "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
9161         }
9162     }
9163
9164     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9165     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
9166     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
9167     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9168     color = getPixelColorFromSurface(readback, 8, 8);
9169     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9170             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9171     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
9172     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
9173     color = getPixelColorFromSurface(readback, 8, 8);
9174     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
9175             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9176
9177     hr = IDirect3DDevice9_SetPixelShader(device, ps2);
9178     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9179
9180     hr = IDirect3DDevice9_BeginScene(device);
9181     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9182     if(SUCCEEDED(hr)) {
9183         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9184         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9185
9186         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9187         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
9188         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9189         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9190         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9191         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9192         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9193         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9194         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9195         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9196
9197         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9198         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9199         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9200         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9201
9202         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9203         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9204         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9205         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9206
9207         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9208         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9209
9210         hr = IDirect3DDevice9_EndScene(device);
9211         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9212     }
9213
9214     color = getPixelColor(device, 160, 240);
9215     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9216     color = getPixelColor(device, 480, 240);
9217     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9218     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9219
9220     IDirect3DPixelShader9_Release(ps2);
9221     IDirect3DPixelShader9_Release(ps1);
9222     IDirect3DVertexShader9_Release(vs);
9223     IDirect3DTexture9_Release(tex1);
9224     IDirect3DTexture9_Release(tex2);
9225     IDirect3DSurface9_Release(surf1);
9226     IDirect3DSurface9_Release(surf2);
9227     IDirect3DSurface9_Release(backbuf);
9228     IDirect3DSurface9_Release(readback);
9229 }
9230
9231 struct formats {
9232     const char *fmtName;
9233     D3DFORMAT textureFormat;
9234     DWORD resultColorBlending;
9235     DWORD resultColorNoBlending;
9236 };
9237
9238 static const struct formats test_formats[] = {
9239   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9240   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9241   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9242   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9243   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9244   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9245   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9246   { NULL, 0 }
9247 };
9248
9249 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9250 {
9251     HRESULT hr;
9252     IDirect3DTexture9 *offscreenTexture = NULL;
9253     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9254     IDirect3D9 *d3d = NULL;
9255     DWORD color;
9256     DWORD r0, g0, b0, r1, g1, b1;
9257     int fmt_index;
9258
9259     static const float quad[][5] = {
9260         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9261         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
9262         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9263         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
9264     };
9265
9266     /* Quad with R=0x10, G=0x20 */
9267     static const struct vertex quad1[] = {
9268         {-1.0f, -1.0f, 0.1f, 0x80102000},
9269         {-1.0f,  1.0f, 0.1f, 0x80102000},
9270         { 1.0f, -1.0f, 0.1f, 0x80102000},
9271         { 1.0f,  1.0f, 0.1f, 0x80102000},
9272     };
9273
9274     /* Quad with R=0x20, G=0x10 */
9275     static const struct vertex quad2[] = {
9276         {-1.0f, -1.0f, 0.1f, 0x80201000},
9277         {-1.0f,  1.0f, 0.1f, 0x80201000},
9278         { 1.0f, -1.0f, 0.1f, 0x80201000},
9279         { 1.0f,  1.0f, 0.1f, 0x80201000},
9280     };
9281
9282     IDirect3DDevice9_GetDirect3D(device, &d3d);
9283
9284     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9285     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9286     if(!backbuffer) {
9287         goto out;
9288     }
9289
9290     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9291     {
9292         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9293
9294         if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9295                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
9296         {
9297             skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
9298             continue;
9299         }
9300
9301         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9302         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9303
9304         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9305         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9306         if(!offscreenTexture) {
9307             continue;
9308         }
9309
9310         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9311         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9312         if(!offscreen) {
9313             continue;
9314         }
9315
9316         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9317         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9318
9319         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9320         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9321         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9322         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9323         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9324         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9325         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9326         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9327         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9328         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9329
9330         /* Below we will draw two quads with different colors and try to blend them together.
9331          * The result color is compared with the expected outcome.
9332          */
9333         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9334             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9335             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9336             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9337             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9338
9339             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9340             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9341
9342             /* Draw a quad using color 0x0010200 */
9343             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9344             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9345             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9346             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9347             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9348             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9349
9350             /* Draw a quad using color 0x0020100 */
9351             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9352             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9353             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9354             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9355             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9356             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9357
9358             /* We don't want to blend the result on the backbuffer */
9359             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9360             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9361
9362             /* Prepare rendering the 'blended' texture quad to the backbuffer */
9363             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9364             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9365             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9366             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9367
9368             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9369             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9370
9371             /* This time with the texture */
9372             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9373             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9374
9375             IDirect3DDevice9_EndScene(device);
9376         }
9377
9378         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9379             /* Compare the color of the center quad with our expectation */
9380             color = getPixelColor(device, 320, 240);
9381             r0 = (color & 0x00ff0000) >> 16;
9382             g0 = (color & 0x0000ff00) >>  8;
9383             b0 = (color & 0x000000ff) >>  0;
9384
9385             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9386             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9387             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9388
9389             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9390                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9391                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9392                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9393         } else {
9394             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9395              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9396              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9397             color = getPixelColor(device, 320, 240);
9398             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);
9399         }
9400         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9401
9402         IDirect3DDevice9_SetTexture(device, 0, NULL);
9403         if(offscreenTexture) {
9404             IDirect3DTexture9_Release(offscreenTexture);
9405         }
9406         if(offscreen) {
9407             IDirect3DSurface9_Release(offscreen);
9408         }
9409     }
9410
9411 out:
9412     /* restore things */
9413     if(backbuffer) {
9414         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9415         IDirect3DSurface9_Release(backbuffer);
9416     }
9417 }
9418
9419 static void tssargtemp_test(IDirect3DDevice9 *device)
9420 {
9421     HRESULT hr;
9422     DWORD color;
9423     static const struct vertex quad[] = {
9424         {-1.0,     -1.0,    0.1,    0x00ff0000},
9425         { 1.0,     -1.0,    0.1,    0x00ff0000},
9426         {-1.0,      1.0,    0.1,    0x00ff0000},
9427         { 1.0,      1.0,    0.1,    0x00ff0000}
9428     };
9429     D3DCAPS9 caps;
9430
9431     memset(&caps, 0, sizeof(caps));
9432     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9433     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9434     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9435         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9436         return;
9437     }
9438
9439     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9440     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9441
9442     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9443     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9444     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9445     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9446
9447     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9448     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9449     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9450     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9451     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9452     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9453
9454     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9455     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9456     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9457     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9458     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9459     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9460
9461     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9462     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9463
9464     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9465     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9466     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9467     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9468
9469     hr = IDirect3DDevice9_BeginScene(device);
9470     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9471     if(SUCCEEDED(hr)) {
9472         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9473         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9474         hr = IDirect3DDevice9_EndScene(device);
9475         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9476     }
9477     color = getPixelColor(device, 320, 240);
9478     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9479     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9480
9481     /* Set stage 1 back to default */
9482     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9483     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9484     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9485     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9486     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9487     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9488     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9489     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9490     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9491     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9492 }
9493
9494 struct testdata
9495 {
9496     DWORD idxVertex; /* number of instances in the first stream */
9497     DWORD idxColor; /* number of instances in the second stream */
9498     DWORD idxInstance; /* should be 1 ?? */
9499     DWORD color1; /* color 1 instance */
9500     DWORD color2; /* color 2 instance */
9501     DWORD color3; /* color 3 instance */
9502     DWORD color4; /* color 4 instance */
9503     WORD strVertex; /* specify which stream to use 0-2*/
9504     WORD strColor;
9505     WORD strInstance;
9506 };
9507
9508 static const struct testdata testcases[]=
9509 {
9510     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9511     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9512     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9513     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9514     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  4 */
9515     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9516     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9517     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9518     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  8 */
9519     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /*  9 */
9520     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9521     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9522     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9523     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9524 /*
9525     This draws one instance on some machines, no instance on others
9526     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9527 */
9528 /*
9529     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9530     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9531 */
9532 };
9533
9534 /* Drawing Indexed Geometry with instances*/
9535 static void stream_test(IDirect3DDevice9 *device)
9536 {
9537     IDirect3DVertexBuffer9 *vb = NULL;
9538     IDirect3DVertexBuffer9 *vb2 = NULL;
9539     IDirect3DVertexBuffer9 *vb3 = NULL;
9540     IDirect3DIndexBuffer9 *ib = NULL;
9541     IDirect3DVertexDeclaration9 *pDecl = NULL;
9542     IDirect3DVertexShader9 *shader = NULL;
9543     HRESULT hr;
9544     BYTE *data;
9545     DWORD color;
9546     DWORD ind;
9547     unsigned i;
9548
9549     const DWORD shader_code[] =
9550     {
9551         0xfffe0101,                                     /* vs_1_1 */
9552         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9553         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9554         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9555         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9556         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9557         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9558         0x0000ffff
9559     };
9560
9561     const float quad[][3] =
9562     {
9563         {-0.5f, -0.5f,  1.1f}, /*0 */
9564         {-0.5f,  0.5f,  1.1f}, /*1 */
9565         { 0.5f, -0.5f,  1.1f}, /*2 */
9566         { 0.5f,  0.5f,  1.1f}, /*3 */
9567     };
9568
9569     const float vertcolor[][4] =
9570     {
9571         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9572         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9573         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9574         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9575     };
9576
9577     /* 4 position for 4 instances */
9578     const float instancepos[][3] =
9579     {
9580         {-0.6f,-0.6f, 0.0f},
9581         { 0.6f,-0.6f, 0.0f},
9582         { 0.6f, 0.6f, 0.0f},
9583         {-0.6f, 0.6f, 0.0f},
9584     };
9585
9586     short indices[] = {0, 1, 2, 1, 2, 3};
9587
9588     D3DVERTEXELEMENT9 decl[] =
9589     {
9590         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9591         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9592         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9593         D3DDECL_END()
9594     };
9595
9596     /* set the default value because it isn't done in wine? */
9597     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9598     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9599
9600     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9601     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9602     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9603
9604     /* check wrong cases */
9605     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9606     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9607     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9608     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9609     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9610     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9611     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9612     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9613     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9614     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9615     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9616     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9617     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9618     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9619     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9620     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9621     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9622     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9623     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9624     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9625
9626     /* set the default value back */
9627     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9628     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9629
9630     /* create all VertexBuffers*/
9631     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9632     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9633     if(!vb) {
9634         skip("Failed to create a vertex buffer\n");
9635         return;
9636     }
9637     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9638     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9639     if(!vb2) {
9640         skip("Failed to create a vertex buffer\n");
9641         goto out;
9642     }
9643     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9644     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9645     if(!vb3) {
9646         skip("Failed to create a vertex buffer\n");
9647         goto out;
9648     }
9649
9650     /* create IndexBuffer*/
9651     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9652     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9653     if(!ib) {
9654         skip("Failed to create a index buffer\n");
9655         goto out;
9656     }
9657
9658     /* copy all Buffers (Vertex + Index)*/
9659     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9660     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9661     memcpy(data, quad, sizeof(quad));
9662     hr = IDirect3DVertexBuffer9_Unlock(vb);
9663     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9664     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9665     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9666     memcpy(data, vertcolor, sizeof(vertcolor));
9667     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9668     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9669     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9670     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9671     memcpy(data, instancepos, sizeof(instancepos));
9672     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9673     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9674     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9675     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9676     memcpy(data, indices, sizeof(indices));
9677     hr = IDirect3DIndexBuffer9_Unlock(ib);
9678     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9679
9680     /* create VertexShader */
9681     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9682     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9683     if(!shader) {
9684         skip("Failed to create a vetex shader\n");
9685         goto out;
9686     }
9687
9688     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9689     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9690
9691     hr = IDirect3DDevice9_SetIndices(device, ib);
9692     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9693
9694     /* run all tests */
9695     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9696     {
9697         struct testdata act = testcases[i];
9698         decl[0].Stream = act.strVertex;
9699         decl[1].Stream = act.strColor;
9700         decl[2].Stream = act.strInstance;
9701         /* create VertexDeclarations */
9702         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9703         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9704
9705         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9706         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9707
9708         hr = IDirect3DDevice9_BeginScene(device);
9709         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9710         if(SUCCEEDED(hr))
9711         {
9712             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9713             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9714
9715             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9716             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9717             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9718             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9719
9720             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9721             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9722             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9723             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9724
9725             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9726             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9727             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9728             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9729
9730             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9731             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9732             hr = IDirect3DDevice9_EndScene(device);
9733             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9734
9735             /* set all StreamSource && StreamSourceFreq back to default */
9736             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9737             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9738             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9739             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9740             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9741             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9742             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9743             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9744             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9745             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9746             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9747             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9748         }
9749
9750         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9751         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9752
9753         color = getPixelColor(device, 160, 360);
9754         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9755         color = getPixelColor(device, 480, 360);
9756         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9757         color = getPixelColor(device, 480, 120);
9758         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9759         color = getPixelColor(device, 160, 120);
9760         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9761
9762         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9763         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9764     }
9765
9766     hr = IDirect3DDevice9_SetIndices(device, NULL);
9767     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9768
9769 out:
9770     if(vb) IDirect3DVertexBuffer9_Release(vb);
9771     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9772     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9773     if(ib)IDirect3DIndexBuffer9_Release(ib);
9774     if(shader)IDirect3DVertexShader9_Release(shader);
9775 }
9776
9777 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9778     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9779     IDirect3DTexture9 *dsttex = NULL;
9780     HRESULT hr;
9781     DWORD color;
9782     D3DRECT r1 = {0,  0,  50,  50 };
9783     D3DRECT r2 = {50, 0,  100, 50 };
9784     D3DRECT r3 = {50, 50, 100, 100};
9785     D3DRECT r4 = {0,  50,  50, 100};
9786     const float quad[] = {
9787         -1.0,   -1.0,   0.1,    0.0,    0.0,
9788          1.0,   -1.0,   0.1,    1.0,    0.0,
9789         -1.0,    1.0,   0.1,    0.0,    1.0,
9790          1.0,    1.0,   0.1,    1.0,    1.0,
9791     };
9792
9793     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9794     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9795
9796     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9797     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9798     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9799     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9800
9801     if(!src || !dsttex) {
9802         skip("One or more test resources could not be created\n");
9803         goto cleanup;
9804     }
9805
9806     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9807     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9808
9809     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9810     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9811
9812     /* Clear the StretchRect destination for debugging */
9813     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9814     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9815     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9816     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9817
9818     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9819     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9820
9821     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9822     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9823     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9824     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9825     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9826     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9827     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9828     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9829
9830     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9831      * the target -> texture GL blit path
9832      */
9833     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9834     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9835     IDirect3DSurface9_Release(dst);
9836
9837     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9838     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9839
9840     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9841     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9842     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9843     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9844     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9845     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9846     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9847     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9848
9849     hr = IDirect3DDevice9_BeginScene(device);
9850     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9851     if(SUCCEEDED(hr)) {
9852         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9853         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9854         hr = IDirect3DDevice9_EndScene(device);
9855         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9856     }
9857
9858     color = getPixelColor(device, 160, 360);
9859     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9860     color = getPixelColor(device, 480, 360);
9861     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9862     color = getPixelColor(device, 480, 120);
9863     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9864     color = getPixelColor(device, 160, 120);
9865     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9866     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9867     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9868
9869     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9870     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9871     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9872     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9873
9874 cleanup:
9875     if(src) IDirect3DSurface9_Release(src);
9876     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9877     if(dsttex) IDirect3DTexture9_Release(dsttex);
9878 }
9879
9880 static void texop_test(IDirect3DDevice9 *device)
9881 {
9882     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9883     IDirect3DTexture9 *texture = NULL;
9884     D3DLOCKED_RECT locked_rect;
9885     D3DCOLOR color;
9886     D3DCAPS9 caps;
9887     HRESULT hr;
9888     unsigned i;
9889
9890     static const struct {
9891         float x, y, z;
9892         float s, t;
9893         D3DCOLOR diffuse;
9894     } quad[] = {
9895         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9896         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9897         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9898         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9899     };
9900
9901     static const D3DVERTEXELEMENT9 decl_elements[] = {
9902         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9903         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9904         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9905         D3DDECL_END()
9906     };
9907
9908     static const struct {
9909         D3DTEXTUREOP op;
9910         const char *name;
9911         DWORD caps_flag;
9912         D3DCOLOR result;
9913     } test_data[] = {
9914         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9915         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9916         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9917         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9918         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9919         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9920         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9921         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9922         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9923         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9924         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9925         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9926         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9927         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9928         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9929         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9930         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9931         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9932         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9933         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9934         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9935         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9936         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9937     };
9938
9939     memset(&caps, 0, sizeof(caps));
9940     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9941     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9942
9943     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9944     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9945     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9946     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9947
9948     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9949     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9950     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9951     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9952     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9953     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9954     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9955     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9956     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9957
9958     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9959     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9960     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9961     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9962     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9963     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9964
9965     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9966     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9967
9968     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9969     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9970     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9971     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9972     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9973     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9974
9975     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9976     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9977
9978     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9979     {
9980         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9981         {
9982             skip("tex operation %s not supported\n", test_data[i].name);
9983             continue;
9984         }
9985
9986         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9987         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9988
9989         hr = IDirect3DDevice9_BeginScene(device);
9990         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9991
9992         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9993         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9994
9995         hr = IDirect3DDevice9_EndScene(device);
9996         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9997
9998         color = getPixelColor(device, 320, 240);
9999         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
10000                 test_data[i].name, color, test_data[i].result);
10001
10002         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10003         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10004     }
10005
10006     if (texture) IDirect3DTexture9_Release(texture);
10007     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
10008 }
10009
10010 static void yuv_color_test(IDirect3DDevice9 *device) {
10011     HRESULT hr;
10012     IDirect3DSurface9 *surface = NULL, *target = NULL;
10013     unsigned int fmt, i;
10014     D3DFORMAT format;
10015     const char *fmt_string;
10016     D3DLOCKED_RECT lr;
10017     IDirect3D9 *d3d;
10018     HRESULT color;
10019     DWORD ref_color_left, ref_color_right;
10020
10021     struct {
10022         DWORD in;           /* The input color */
10023         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
10024         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
10025         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
10026         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
10027     } test_data[] = {
10028     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
10029      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
10030      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
10031      * that
10032      */
10033       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
10034       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
10035       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
10036       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
10037       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
10038       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
10039       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
10040       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
10041       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
10042       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
10043       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
10044       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
10045       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
10046       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
10047
10048       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
10049       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
10050       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
10051       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
10052     };
10053
10054     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
10055     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
10056     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
10057     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
10058
10059     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
10060     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10061
10062     for(fmt = 0; fmt < 2; fmt++) {
10063         if(fmt == 0) {
10064             format = D3DFMT_UYVY;
10065             fmt_string = "D3DFMT_UYVY";
10066         } else {
10067             format = D3DFMT_YUY2;
10068             fmt_string = "D3DFMT_YUY2";
10069         }
10070
10071         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
10072                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
10073                        */
10074         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
10075                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
10076             skip("%s is not supported\n", fmt_string);
10077             continue;
10078         }
10079
10080         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
10081         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
10082         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
10083
10084         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
10085             if(fmt == 0) {
10086                 ref_color_left = test_data[i].uyvy_left;
10087                 ref_color_right = test_data[i].uyvy_right;
10088             } else {
10089                 ref_color_left = test_data[i].yuy2_left;
10090                 ref_color_right = test_data[i].yuy2_right;
10091             }
10092
10093             memset(&lr, 0, sizeof(lr));
10094             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
10095             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
10096             *((DWORD *) lr.pBits) = test_data[i].in;
10097             hr = IDirect3DSurface9_UnlockRect(surface);
10098             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10099
10100             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10101             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10102             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10103             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10104
10105             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10106              * prevent running into precision problems, read a far left and far right pixel. In the future we may
10107              * want to add tests for the filtered pixels as well.
10108              *
10109              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10110              * differently, so we need a max diff of 16
10111              */
10112             color = getPixelColor(device, 40, 240);
10113
10114             /* Newer versions of the Nvidia Windows driver mix up the U and V channels, breaking all the tests
10115              * where U != V. Skip the entire test if this bug in this case
10116              */
10117             if (broken(test_data[i].in == 0xff000000 && color == 0x00008800 && format == D3DFMT_UYVY))
10118             {
10119                 skip("Nvidia channel confusion bug detected, skipping YUV tests\n");
10120                 IDirect3DSurface9_Release(surface);
10121                 goto out;
10122             }
10123
10124             ok(color_match(color, ref_color_left, 18),
10125                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10126                test_data[i].in, color, ref_color_left, fmt_string);
10127             color = getPixelColor(device, 600, 240);
10128             ok(color_match(color, ref_color_right, 18),
10129                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10130                test_data[i].in, color, ref_color_right, fmt_string);
10131             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10132             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10133         }
10134         IDirect3DSurface9_Release(surface);
10135     }
10136
10137 out:
10138     IDirect3DSurface9_Release(target);
10139     IDirect3D9_Release(d3d);
10140 }
10141
10142 static void texop_range_test(IDirect3DDevice9 *device)
10143 {
10144     static const struct {
10145         float x, y, z;
10146         D3DCOLOR diffuse;
10147     } quad[] = {
10148         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10149         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10150         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10151         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10152     };
10153     HRESULT hr;
10154     IDirect3DTexture9 *texture;
10155     D3DLOCKED_RECT locked_rect;
10156     D3DCAPS9 caps;
10157     DWORD color;
10158
10159     /* We need ADD and SUBTRACT operations */
10160     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10161     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10162     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10163         skip("D3DTOP_ADD is not supported, skipping value range test\n");
10164         return;
10165     }
10166     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10167         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10168         return;
10169     }
10170
10171     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10172     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10173     /* Stage 1: result = diffuse(=1.0) + diffuse
10174      * stage 2: result = result - tfactor(= 0.5)
10175      */
10176     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10177     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10178     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10179     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10180     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10181     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10182     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10183     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10184     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10185     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10186     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10187     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10188     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10189     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10190
10191     hr = IDirect3DDevice9_BeginScene(device);
10192     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10193     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10194     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10195     hr = IDirect3DDevice9_EndScene(device);
10196     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10197
10198     color = getPixelColor(device, 320, 240);
10199     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10200        color);
10201     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10202     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10203
10204     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10205     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10206     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10207     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10208     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10209     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10210     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10211     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10212     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10213
10214     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10215      * stage 2: result = result + diffuse(1.0)
10216      */
10217     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10218     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10219     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10220     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10221     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10222     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10223     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10224     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10225     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10226     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10227     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10228     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10229     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10230     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10231
10232     hr = IDirect3DDevice9_BeginScene(device);
10233     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10234     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10235     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10236     hr = IDirect3DDevice9_EndScene(device);
10237     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10238
10239     color = getPixelColor(device, 320, 240);
10240     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10241        color);
10242     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10243     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10244
10245     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10246     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10247     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10248     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10249     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10250     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10251     IDirect3DTexture9_Release(texture);
10252 }
10253
10254 static void alphareplicate_test(IDirect3DDevice9 *device) {
10255     struct vertex quad[] = {
10256         { -1.0,    -1.0,    0.1,    0x80ff00ff },
10257         {  1.0,    -1.0,    0.1,    0x80ff00ff },
10258         { -1.0,     1.0,    0.1,    0x80ff00ff },
10259         {  1.0,     1.0,    0.1,    0x80ff00ff },
10260     };
10261     HRESULT hr;
10262     DWORD color;
10263
10264     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10265     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10266
10267     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10268     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10269
10270     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10271     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10272     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10273     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10274
10275     hr = IDirect3DDevice9_BeginScene(device);
10276     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10277     if(SUCCEEDED(hr)) {
10278         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10279         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10280         hr = IDirect3DDevice9_EndScene(device);
10281         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10282     }
10283
10284     color = getPixelColor(device, 320, 240);
10285     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10286        color);
10287     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10288     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10289
10290     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10291     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10292
10293 }
10294
10295 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10296     HRESULT hr;
10297     D3DCAPS9 caps;
10298     DWORD color;
10299     struct vertex quad[] = {
10300         { -1.0,    -1.0,    0.1,    0x408080c0 },
10301         {  1.0,    -1.0,    0.1,    0x408080c0 },
10302         { -1.0,     1.0,    0.1,    0x408080c0 },
10303         {  1.0,     1.0,    0.1,    0x408080c0 },
10304     };
10305
10306     memset(&caps, 0, sizeof(caps));
10307     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10308     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10309     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10310         skip("D3DTOP_DOTPRODUCT3 not supported\n");
10311         return;
10312     }
10313
10314     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10315     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10316
10317     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10318     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10319
10320     /* dp3_x4 r0, diffuse_bias, tfactor_bias
10321      * mov r0.a, diffuse.a
10322      * mov r0, r0.a
10323      *
10324      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10325      * 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
10326      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10327      */
10328     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10329     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10330     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10331     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10332     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10333     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10334     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10335     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10336     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10337     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10338     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10339     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10340     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10341     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10342     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10343     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10344     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10345     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10346
10347     hr = IDirect3DDevice9_BeginScene(device);
10348     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10349     if(SUCCEEDED(hr)) {
10350         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10351         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10352         hr = IDirect3DDevice9_EndScene(device);
10353         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10354     }
10355
10356     color = getPixelColor(device, 320, 240);
10357     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10358        color);
10359     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10360     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10361
10362     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10363     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10364     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10365     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10366     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10367     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10368 }
10369
10370 static void zwriteenable_test(IDirect3DDevice9 *device) {
10371     HRESULT hr;
10372     DWORD color;
10373     struct vertex quad1[] = {
10374         { -1.0,  -1.0,  0.1,    0x00ff0000},
10375         { -1.0,   1.0,  0.1,    0x00ff0000},
10376         {  1.0,  -1.0,  0.1,    0x00ff0000},
10377         {  1.0,   1.0,  0.1,    0x00ff0000},
10378     };
10379     struct vertex quad2[] = {
10380         { -1.0,  -1.0,  0.9,    0x0000ff00},
10381         { -1.0,   1.0,  0.9,    0x0000ff00},
10382         {  1.0,  -1.0,  0.9,    0x0000ff00},
10383         {  1.0,   1.0,  0.9,    0x0000ff00},
10384     };
10385
10386     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10387     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10388
10389     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10390     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10391     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10392     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10393     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10394     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10395     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10396     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10397
10398     hr = IDirect3DDevice9_BeginScene(device);
10399     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10400     if(SUCCEEDED(hr)) {
10401         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10402          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10403          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10404          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10405          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10406          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10407          */
10408         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10409         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10410         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10411         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10412         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10413         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10414
10415         hr = IDirect3DDevice9_EndScene(device);
10416         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10417     }
10418
10419     color = getPixelColor(device, 320, 240);
10420     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10421        color);
10422     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10423     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10424
10425     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10426     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10427 }
10428
10429 static void alphatest_test(IDirect3DDevice9 *device) {
10430 #define ALPHATEST_PASSED 0x0000ff00
10431 #define ALPHATEST_FAILED 0x00ff0000
10432     struct {
10433         D3DCMPFUNC  func;
10434         DWORD       color_less;
10435         DWORD       color_equal;
10436         DWORD       color_greater;
10437     } testdata[] = {
10438         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10439         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10440         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10441         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10442         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10443         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10444         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10445         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10446     };
10447     unsigned int i, j;
10448     HRESULT hr;
10449     DWORD color;
10450     struct vertex quad[] = {
10451         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10452         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10453         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10454         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10455     };
10456     D3DCAPS9 caps;
10457
10458     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10459     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10460     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10461     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10462
10463     for(j = 0; j < 2; j++) {
10464         if(j == 1) {
10465             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10466              * the alpha test either for performance reasons(floating point RTs) or to work
10467              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10468              * codepath for ffp and shader in this case, and the test should cover both
10469              */
10470             IDirect3DPixelShader9 *ps;
10471             DWORD shader_code[] = {
10472                 0xffff0101,                                 /* ps_1_1           */
10473                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10474                 0x0000ffff                                  /* end              */
10475             };
10476             memset(&caps, 0, sizeof(caps));
10477             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10478             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10479             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10480                 break;
10481             }
10482
10483             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10484             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10485             IDirect3DDevice9_SetPixelShader(device, ps);
10486             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10487             IDirect3DPixelShader9_Release(ps);
10488         }
10489
10490         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10491             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10492             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10493
10494             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10495             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10496             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10497             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10498             hr = IDirect3DDevice9_BeginScene(device);
10499             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10500             if(SUCCEEDED(hr)) {
10501                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10502                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10503                 hr = IDirect3DDevice9_EndScene(device);
10504                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10505             }
10506             color = getPixelColor(device, 320, 240);
10507             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10508             color, testdata[i].color_less, testdata[i].func);
10509             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10510             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10511
10512             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10513             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10514             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10515             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10516             hr = IDirect3DDevice9_BeginScene(device);
10517             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10518             if(SUCCEEDED(hr)) {
10519                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10520                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10521                 hr = IDirect3DDevice9_EndScene(device);
10522                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10523             }
10524             color = getPixelColor(device, 320, 240);
10525             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10526             color, testdata[i].color_equal, testdata[i].func);
10527             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10528             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10529
10530             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10531             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10532             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10533             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10534             hr = IDirect3DDevice9_BeginScene(device);
10535             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10536             if(SUCCEEDED(hr)) {
10537                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10538                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10539                 hr = IDirect3DDevice9_EndScene(device);
10540                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10541             }
10542             color = getPixelColor(device, 320, 240);
10543             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10544             color, testdata[i].color_greater, testdata[i].func);
10545             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10546             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10547         }
10548     }
10549
10550     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10551     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10552     IDirect3DDevice9_SetPixelShader(device, NULL);
10553     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10554 }
10555
10556 static void sincos_test(IDirect3DDevice9 *device) {
10557     const DWORD sin_shader_code[] = {
10558         0xfffe0200,                                                                 /* vs_2_0                       */
10559         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10560         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10561         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10562         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10563         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10564         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10565         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10566         0x0000ffff                                                                  /* end                          */
10567     };
10568     const DWORD cos_shader_code[] = {
10569         0xfffe0200,                                                                 /* vs_2_0                       */
10570         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10571         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10572         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10573         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10574         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10575         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10576         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10577         0x0000ffff                                                                  /* end                          */
10578     };
10579     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10580     HRESULT hr;
10581     struct {
10582         float x, y, z;
10583     } data[1280];
10584     unsigned int i;
10585     float sincosc1[4] = {D3DSINCOSCONST1};
10586     float sincosc2[4] = {D3DSINCOSCONST2};
10587
10588     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10589     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10590
10591     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10592     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10593     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10594     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10595     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10596     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10597     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10598     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10599     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10600     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10601
10602     /* Generate a point from -1 to 1 every 0.5 pixels */
10603     for(i = 0; i < 1280; i++) {
10604         data[i].x = (-640.0 + i) / 640.0;
10605         data[i].y = 0.0;
10606         data[i].z = 0.1;
10607     }
10608
10609     hr = IDirect3DDevice9_BeginScene(device);
10610     if(SUCCEEDED(hr)) {
10611         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10612         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10613         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10614         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10615
10616         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10617         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10618         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10619         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10620
10621         hr = IDirect3DDevice9_EndScene(device);
10622         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10623     }
10624     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10625     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10626     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10627
10628     IDirect3DDevice9_SetVertexShader(device, NULL);
10629     IDirect3DVertexShader9_Release(sin_shader);
10630     IDirect3DVertexShader9_Release(cos_shader);
10631 }
10632
10633 static void loop_index_test(IDirect3DDevice9 *device) {
10634     const DWORD shader_code[] = {
10635         0xfffe0200,                                                 /* vs_2_0                   */
10636         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10637         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10638         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10639         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10640         0x0000001d,                                                 /* endloop                  */
10641         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10642         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10643         0x0000ffff                                                  /* END                      */
10644     };
10645     IDirect3DVertexShader9 *shader;
10646     HRESULT hr;
10647     DWORD color;
10648     const float quad[] = {
10649         -1.0,   -1.0,   0.1,
10650          1.0,   -1.0,   0.1,
10651         -1.0,    1.0,   0.1,
10652          1.0,    1.0,   0.1
10653     };
10654     const float zero[4] = {0, 0, 0, 0};
10655     const float one[4] = {1, 1, 1, 1};
10656     int i0[4] = {2, 10, -3, 0};
10657     float values[4];
10658
10659     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10660     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10661     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10662     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10663     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10664     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10665     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10666     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10667
10668     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10669     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10670     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10671     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10672     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10673     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10674     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10675     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10676     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10677     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10678     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10679     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10680     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10681     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10682     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10683     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10684     values[0] = 1.0;
10685     values[1] = 1.0;
10686     values[2] = 0.0;
10687     values[3] = 0.0;
10688     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10689     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10690     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10691     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10692     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10693     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10694     values[0] = -1.0;
10695     values[1] = 0.0;
10696     values[2] = 0.0;
10697     values[3] = 0.0;
10698     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10699     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10700     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10701     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10702     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10703     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10704     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10705     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10706     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10707     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10708
10709     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10710     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10711
10712     hr = IDirect3DDevice9_BeginScene(device);
10713     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10714     if(SUCCEEDED(hr))
10715     {
10716         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10717         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10718         hr = IDirect3DDevice9_EndScene(device);
10719         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10720     }
10721     color = getPixelColor(device, 320, 240);
10722     ok(color_match(color, 0x0000ff00, 1),
10723        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10724     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10725     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10726
10727     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10728     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10729     IDirect3DVertexShader9_Release(shader);
10730 }
10731
10732 static void sgn_test(IDirect3DDevice9 *device) {
10733     const DWORD shader_code[] = {
10734         0xfffe0200,                                                             /* vs_2_0                       */
10735         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10736         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10737         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10738         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10739         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10740         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10741         0x0000ffff                                                              /* end                          */
10742     };
10743     IDirect3DVertexShader9 *shader;
10744     HRESULT hr;
10745     DWORD color;
10746     const float quad[] = {
10747         -1.0,   -1.0,   0.1,
10748          1.0,   -1.0,   0.1,
10749         -1.0,    1.0,   0.1,
10750          1.0,    1.0,   0.1
10751     };
10752
10753     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10754     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10755     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10756     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10757     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10758     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10759     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10760     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10761
10762     hr = IDirect3DDevice9_BeginScene(device);
10763     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10764     if(SUCCEEDED(hr))
10765     {
10766         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10767         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10768         hr = IDirect3DDevice9_EndScene(device);
10769         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10770     }
10771     color = getPixelColor(device, 320, 240);
10772     ok(color_match(color, 0x008000ff, 1),
10773        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10774     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10775     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10776
10777     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10778     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10779     IDirect3DVertexShader9_Release(shader);
10780 }
10781
10782 static void viewport_test(IDirect3DDevice9 *device) {
10783     HRESULT hr;
10784     DWORD color;
10785     D3DVIEWPORT9 vp, old_vp;
10786     BOOL draw_failed = TRUE;
10787     const float quad[] =
10788     {
10789         -0.5,   -0.5,   0.1,
10790          0.5,   -0.5,   0.1,
10791         -0.5,    0.5,   0.1,
10792          0.5,    0.5,   0.1
10793     };
10794
10795     memset(&old_vp, 0, sizeof(old_vp));
10796     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10797     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10798
10799     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10800     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10801
10802     /* Test a viewport with Width and Height bigger than the surface dimensions
10803      *
10804      * TODO: Test Width < surface.width, but X + Width > surface.width
10805      * TODO: Test Width < surface.width, what happens with the height?
10806      *
10807      * The expected behavior is that the viewport behaves like the "default"
10808      * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
10809      * MinZ = 0.0, MaxZ = 1.0.
10810      *
10811      * Starting with Windows 7 the behavior among driver versions is not
10812      * consistent. The SetViewport call is accepted on all drivers. Some
10813      * drivers(older nvidia ones) refuse to draw and return an error. Newer
10814      * nvidia drivers draw, but use the actual values in the viewport and only
10815      * display the upper left part on the surface.
10816      */
10817     memset(&vp, 0, sizeof(vp));
10818     vp.X = 0;
10819     vp.Y = 0;
10820     vp.Width = 10000;
10821     vp.Height = 10000;
10822     vp.MinZ = 0.0;
10823     vp.MaxZ = 0.0;
10824     hr = IDirect3DDevice9_SetViewport(device, &vp);
10825     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10826
10827     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10828     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10829     hr = IDirect3DDevice9_BeginScene(device);
10830     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10831     if(SUCCEEDED(hr))
10832     {
10833         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10834         ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10835         draw_failed = FAILED(hr);
10836         hr = IDirect3DDevice9_EndScene(device);
10837         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10838     }
10839
10840     if(!draw_failed)
10841     {
10842         color = getPixelColor(device, 158, 118);
10843         ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10844         color = getPixelColor(device, 162, 118);
10845         ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10846         color = getPixelColor(device, 158, 122);
10847         ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10848         color = getPixelColor(device, 162, 122);
10849         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
10850
10851         color = getPixelColor(device, 478, 358);
10852         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
10853         color = getPixelColor(device, 482, 358);
10854         ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10855         color = getPixelColor(device, 478, 362);
10856         ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10857         color = getPixelColor(device, 482, 362);
10858         ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10859     }
10860
10861     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10862     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10863
10864     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10865     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10866 }
10867
10868 /* This test tests depth clamping / clipping behaviour:
10869  *   - With software vertex processing, depth values are clamped to the
10870  *     minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
10871  *     when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
10872  *     same as regular vertices here.
10873  *   - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
10874  *     Normal vertices are always clipped. Pretransformed vertices are
10875  *     clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
10876  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10877  */
10878 static void depth_clamp_test(IDirect3DDevice9 *device)
10879 {
10880     const struct tvertex quad1[] =
10881     {
10882         {  0.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
10883         {640.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
10884         {  0.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
10885         {640.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
10886     };
10887     const struct tvertex quad2[] =
10888     {
10889         {  0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10890         {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10891         {  0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10892         {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10893     };
10894     const struct tvertex quad3[] =
10895     {
10896         {112.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
10897         {208.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
10898         {112.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
10899         {208.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
10900     };
10901     const struct tvertex quad4[] =
10902     {
10903         { 42.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
10904         {112.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
10905         { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10906         {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10907     };
10908     const struct vertex quad5[] =
10909     {
10910         { -0.5f,   0.5f, 10.0f,       0xff14f914},
10911         {  0.5f,   0.5f, 10.0f,       0xff14f914},
10912         { -0.5f,  -0.5f, 10.0f,       0xff14f914},
10913         {  0.5f,  -0.5f, 10.0f,       0xff14f914},
10914     };
10915     const struct vertex quad6[] =
10916     {
10917         { -1.0f,   0.5f, 10.0f,      0xfff91414},
10918         {  1.0f,   0.5f, 10.0f,      0xfff91414},
10919         { -1.0f,  0.25f, 10.0f,      0xfff91414},
10920         {  1.0f,  0.25f, 10.0f,      0xfff91414},
10921     };
10922
10923     D3DVIEWPORT9 vp;
10924     D3DCOLOR color;
10925     D3DCAPS9 caps;
10926     HRESULT hr;
10927
10928     vp.X = 0;
10929     vp.Y = 0;
10930     vp.Width = 640;
10931     vp.Height = 480;
10932     vp.MinZ = 0.0;
10933     vp.MaxZ = 7.5;
10934
10935     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10936     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10937
10938     hr = IDirect3DDevice9_SetViewport(device, &vp);
10939     if(FAILED(hr))
10940     {
10941         /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10942          * the tests because the 7.5 is just intended to show that it doesn't have
10943          * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10944          * viewport and continue.
10945          */
10946         ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10947         vp.MaxZ = 1.0;
10948         hr = IDirect3DDevice9_SetViewport(device, &vp);
10949     }
10950     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10951
10952     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
10953     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10954
10955     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10956     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10957     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10958     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10959     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10960     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10961     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10962     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10963
10964     hr = IDirect3DDevice9_BeginScene(device);
10965     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10966
10967     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10968     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10969
10970     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10971     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10972     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10973     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10974
10975     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10976     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10977
10978     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10979     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10980     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10981     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10982
10983     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10984     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10985
10986     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10987     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10988
10989     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10990     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10991
10992     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10993     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10994
10995     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10996     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10997
10998     hr = IDirect3DDevice9_EndScene(device);
10999     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11000
11001     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
11002     {
11003         color = getPixelColor(device, 75, 75);
11004         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11005         color = getPixelColor(device, 150, 150);
11006         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11007         color = getPixelColor(device, 320, 240);
11008         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11009         color = getPixelColor(device, 320, 330);
11010         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11011         color = getPixelColor(device, 320, 330);
11012         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
11013     }
11014     else
11015     {
11016         color = getPixelColor(device, 75, 75);
11017         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11018         color = getPixelColor(device, 150, 150);
11019         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
11020         color = getPixelColor(device, 320, 240);
11021         ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11022         color = getPixelColor(device, 320, 330);
11023         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11024         color = getPixelColor(device, 320, 330);
11025         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11026     }
11027
11028     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11029     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11030
11031     vp.MinZ = 0.0;
11032     vp.MaxZ = 1.0;
11033     hr = IDirect3DDevice9_SetViewport(device, &vp);
11034     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11035 }
11036
11037 static void depth_bounds_test(IDirect3DDevice9 *device)
11038 {
11039     const struct tvertex quad1[] =
11040     {
11041         {    0,    0, 0.0f, 1, 0xfff9e814},
11042         {  640,    0, 0.0f, 1, 0xfff9e814},
11043         {    0,  480, 1.0f, 1, 0xfff9e814},
11044         {  640,  480, 1.0f, 1, 0xfff9e814},
11045     };
11046     const struct tvertex quad2[] =
11047     {
11048         {    0,    0,  0.6f, 1, 0xff002b7f},
11049         {  640,    0,  0.6f, 1, 0xff002b7f},
11050         {    0,  480,  0.6f, 1, 0xff002b7f},
11051         {  640,  480,  0.6f, 1, 0xff002b7f},
11052     };
11053     const struct tvertex quad3[] =
11054     {
11055         {    0,  100, 0.6f, 1, 0xfff91414},
11056         {  640,  100, 0.6f, 1, 0xfff91414},
11057         {    0,  160, 0.6f, 1, 0xfff91414},
11058         {  640,  160, 0.6f, 1, 0xfff91414},
11059     };
11060
11061     union {
11062         DWORD d;
11063         float f;
11064     } tmpvalue;
11065
11066     IDirect3D9 *d3d = NULL;
11067     IDirect3DSurface9 *offscreen_surface = NULL;
11068     D3DCOLOR color;
11069     HRESULT hr;
11070
11071     IDirect3DDevice9_GetDirect3D(device, &d3d);
11072     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11073             0,  D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
11074         skip("No NVDB (depth bounds test) support\n");
11075         IDirect3D9_Release(d3d);
11076         return;
11077     }
11078     IDirect3D9_Release(d3d);
11079
11080     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
11081             MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
11082     ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
11083     if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
11084
11085     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
11086     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11087
11088     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11089     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11090     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
11091     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11092     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11093     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11094     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11095     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11096
11097
11098     hr = IDirect3DDevice9_BeginScene(device);
11099     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11100
11101     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
11102     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11103
11104     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11105     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11106
11107     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
11108     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11109
11110     tmpvalue.f = 0.625;
11111     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11112     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11113
11114     tmpvalue.f = 0.75;
11115     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
11116     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11117
11118     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11119     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11120
11121     tmpvalue.f = 0.75;
11122     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
11123     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11124
11125     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11126     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11127
11128     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
11129     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11130
11131     hr = IDirect3DDevice9_EndScene(device);
11132     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11133
11134     color = getPixelColor(device, 150, 130);
11135     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11136     color = getPixelColor(device, 150, 200);
11137     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11138     color = getPixelColor(device, 150, 300-5);
11139     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11140     color = getPixelColor(device, 150, 300+5);
11141     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11142     color = getPixelColor(device, 150, 330);
11143     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
11144     color = getPixelColor(device, 150, 360-5);
11145     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
11146     color = getPixelColor(device, 150, 360+5);
11147     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
11148
11149     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11150     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11151 }
11152
11153 static void depth_buffer_test(IDirect3DDevice9 *device)
11154 {
11155     static const struct vertex quad1[] =
11156     {
11157         { -1.0,  1.0, 0.33f, 0xff00ff00},
11158         {  1.0,  1.0, 0.33f, 0xff00ff00},
11159         { -1.0, -1.0, 0.33f, 0xff00ff00},
11160         {  1.0, -1.0, 0.33f, 0xff00ff00},
11161     };
11162     static const struct vertex quad2[] =
11163     {
11164         { -1.0,  1.0, 0.50f, 0xffff00ff},
11165         {  1.0,  1.0, 0.50f, 0xffff00ff},
11166         { -1.0, -1.0, 0.50f, 0xffff00ff},
11167         {  1.0, -1.0, 0.50f, 0xffff00ff},
11168     };
11169     static const struct vertex quad3[] =
11170     {
11171         { -1.0,  1.0, 0.66f, 0xffff0000},
11172         {  1.0,  1.0, 0.66f, 0xffff0000},
11173         { -1.0, -1.0, 0.66f, 0xffff0000},
11174         {  1.0, -1.0, 0.66f, 0xffff0000},
11175     };
11176     static const DWORD expected_colors[4][4] =
11177     {
11178         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11179         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11180         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11181         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11182     };
11183
11184     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
11185     unsigned int i, j;
11186     D3DVIEWPORT9 vp;
11187     D3DCOLOR color;
11188     HRESULT hr;
11189
11190     vp.X = 0;
11191     vp.Y = 0;
11192     vp.Width = 640;
11193     vp.Height = 480;
11194     vp.MinZ = 0.0;
11195     vp.MaxZ = 1.0;
11196
11197     hr = IDirect3DDevice9_SetViewport(device, &vp);
11198     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11199
11200     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11201     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11202     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11203     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11204     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11205     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11206     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11207     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11208     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11209     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11210
11211     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11212     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11213     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
11214             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11215     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11216     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11217             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11218     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11219     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11220             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
11221     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11222
11223     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11224     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11225     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11226     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11227
11228     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11229     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11230     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11231     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11232
11233     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11234     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11235     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11236     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11237
11238     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11239     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11240     hr = IDirect3DDevice9_BeginScene(device);
11241     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11242     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11243     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11244     hr = IDirect3DDevice9_EndScene(device);
11245     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11246
11247     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11248     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11249     IDirect3DSurface9_Release(backbuffer);
11250     IDirect3DSurface9_Release(rt3);
11251     IDirect3DSurface9_Release(rt2);
11252     IDirect3DSurface9_Release(rt1);
11253
11254     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11255     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11256
11257     hr = IDirect3DDevice9_BeginScene(device);
11258     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11259     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11260     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11261     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11262     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11263     hr = IDirect3DDevice9_EndScene(device);
11264     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11265
11266     for (i = 0; i < 4; ++i)
11267     {
11268         for (j = 0; j < 4; ++j)
11269         {
11270             unsigned int x = 80 * ((2 * j) + 1);
11271             unsigned int y = 60 * ((2 * i) + 1);
11272             color = getPixelColor(device, x, y);
11273             ok(color_match(color, expected_colors[i][j], 0),
11274                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11275         }
11276     }
11277
11278     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11279     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11280 }
11281
11282 /* Test that partial depth copies work the way they're supposed to. The clear
11283  * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
11284  * the following draw should only copy back the part that was modified. */
11285 static void depth_buffer2_test(IDirect3DDevice9 *device)
11286 {
11287     static const struct vertex quad[] =
11288     {
11289         { -1.0,  1.0, 0.66f, 0xffff0000},
11290         {  1.0,  1.0, 0.66f, 0xffff0000},
11291         { -1.0, -1.0, 0.66f, 0xffff0000},
11292         {  1.0, -1.0, 0.66f, 0xffff0000},
11293     };
11294
11295     IDirect3DSurface9 *backbuffer, *rt1, *rt2;
11296     unsigned int i, j;
11297     D3DVIEWPORT9 vp;
11298     D3DCOLOR color;
11299     HRESULT hr;
11300
11301     vp.X = 0;
11302     vp.Y = 0;
11303     vp.Width = 640;
11304     vp.Height = 480;
11305     vp.MinZ = 0.0;
11306     vp.MaxZ = 1.0;
11307
11308     hr = IDirect3DDevice9_SetViewport(device, &vp);
11309     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11310
11311     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11312     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11313     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11314     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11315     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11316     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11317     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11318     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11319     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11320     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11321
11322     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11323             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11324     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11325     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11326             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11327     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11328     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11329     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11330
11331     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11332     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11333     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11334     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11335
11336     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11337     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11338     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
11339     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11340
11341     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11342     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11343     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11344     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11345
11346     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11347     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11348     IDirect3DSurface9_Release(backbuffer);
11349     IDirect3DSurface9_Release(rt2);
11350     IDirect3DSurface9_Release(rt1);
11351
11352     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11353     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11354
11355     hr = IDirect3DDevice9_BeginScene(device);
11356     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11357     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11358     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11359     hr = IDirect3DDevice9_EndScene(device);
11360     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11361
11362     for (i = 0; i < 4; ++i)
11363     {
11364         for (j = 0; j < 4; ++j)
11365         {
11366             unsigned int x = 80 * ((2 * j) + 1);
11367             unsigned int y = 60 * ((2 * i) + 1);
11368             color = getPixelColor(device, x, y);
11369             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11370                     "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
11371         }
11372     }
11373
11374     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11375     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11376 }
11377
11378 static void depth_blit_test(IDirect3DDevice9 *device)
11379 {
11380     static const struct vertex quad1[] =
11381     {
11382         { -1.0,  1.0, 0.50f, 0xff00ff00},
11383         {  1.0,  1.0, 0.50f, 0xff00ff00},
11384         { -1.0, -1.0, 0.50f, 0xff00ff00},
11385         {  1.0, -1.0, 0.50f, 0xff00ff00},
11386     };
11387     static const struct vertex quad2[] =
11388     {
11389         { -1.0,  1.0, 0.66f, 0xff0000ff},
11390         {  1.0,  1.0, 0.66f, 0xff0000ff},
11391         { -1.0, -1.0, 0.66f, 0xff0000ff},
11392         {  1.0, -1.0, 0.66f, 0xff0000ff},
11393     };
11394     static const DWORD expected_colors[4][4] =
11395     {
11396         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11397         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11398         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11399         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11400     };
11401
11402     IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
11403     RECT src_rect, dst_rect;
11404     unsigned int i, j;
11405     D3DVIEWPORT9 vp;
11406     D3DCOLOR color;
11407     HRESULT hr;
11408
11409     vp.X = 0;
11410     vp.Y = 0;
11411     vp.Width = 640;
11412     vp.Height = 480;
11413     vp.MinZ = 0.0;
11414     vp.MaxZ = 1.0;
11415
11416     hr = IDirect3DDevice9_SetViewport(device, &vp);
11417     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11418
11419     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11420     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11421     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11422     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11423     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11424     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11425     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11426     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11427     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
11428     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11429
11430     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11431     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11432     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11433     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11434     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11435     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11436     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11437     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11438
11439     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11440     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11441     SetRect(&dst_rect, 0, 0, 480, 360);
11442     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11443     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11444     SetRect(&dst_rect, 0, 0, 320, 240);
11445     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11446     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11447
11448     /* Partial blit. */
11449     SetRect(&src_rect, 0, 0, 320, 240);
11450     SetRect(&dst_rect, 0, 0, 320, 240);
11451     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11452     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11453     /* Flipped. */
11454     SetRect(&src_rect, 0, 0, 640, 480);
11455     SetRect(&dst_rect, 0, 480, 640, 0);
11456     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11457     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11458     /* Full, explicit. */
11459     SetRect(&src_rect, 0, 0, 640, 480);
11460     SetRect(&dst_rect, 0, 0, 640, 480);
11461     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11462     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11463     /* Filtered blit. */
11464     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11465     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11466     /* Depth -> color blit.*/
11467     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11468     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11469     IDirect3DSurface9_Release(backbuffer);
11470     /* Full surface, different sizes */
11471     hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
11472     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11473     hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
11474     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11475
11476     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11477     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11478     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11479     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11480     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11481     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11482     IDirect3DSurface9_Release(ds3);
11483     IDirect3DSurface9_Release(ds2);
11484     IDirect3DSurface9_Release(ds1);
11485
11486     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11487     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11488     hr = IDirect3DDevice9_BeginScene(device);
11489     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11490     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11491     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11492     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11493     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11494     hr = IDirect3DDevice9_EndScene(device);
11495     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11496
11497     for (i = 0; i < 4; ++i)
11498     {
11499         for (j = 0; j < 4; ++j)
11500         {
11501             unsigned int x = 80 * ((2 * j) + 1);
11502             unsigned int y = 60 * ((2 * i) + 1);
11503             color = getPixelColor(device, x, y);
11504             ok(color_match(color, expected_colors[i][j], 0),
11505                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11506         }
11507     }
11508
11509     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11510     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11511 }
11512
11513 static void intz_test(IDirect3DDevice9 *device)
11514 {
11515     static const DWORD ps_code[] =
11516     {
11517         0xffff0200,                                                             /* ps_2_0                       */
11518         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11519         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11520         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11521         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11522         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11523         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11524         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11525         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11526         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
11527         0x0000ffff,                                                             /* end                          */
11528     };
11529     struct
11530     {
11531         float x, y, z;
11532         float s, t, p, q;
11533     }
11534     quad[] =
11535     {
11536         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11537         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11538         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11539         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11540     };
11541     struct
11542     {
11543         UINT x, y;
11544         D3DCOLOR color;
11545     }
11546     expected_colors[] =
11547     {
11548         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11549         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11550         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11551         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11552         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11553         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11554         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11555         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11556     };
11557
11558     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11559     IDirect3DTexture9 *texture;
11560     IDirect3DPixelShader9 *ps;
11561     IDirect3DSurface9 *ds;
11562     IDirect3D9 *d3d9;
11563     D3DCAPS9 caps;
11564     HRESULT hr;
11565     UINT i;
11566
11567     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11568     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11569     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11570     {
11571         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11572         return;
11573     }
11574
11575     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11576     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11577
11578     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11579             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11580     if (FAILED(hr))
11581     {
11582         skip("No INTZ support, skipping INTZ test.\n");
11583         return;
11584     }
11585
11586     IDirect3D9_Release(d3d9);
11587
11588     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11589     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11590     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11591     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11592
11593     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11594             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11595     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11596     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11597             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11598     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11599     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11600     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11601
11602     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11603     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11604     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11605     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11606     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11607     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11608     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11609     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11610     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11611     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11612
11613     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11614     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11615     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11616     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11617     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11618     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11619     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11620     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11621     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11622     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11623
11624     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11625     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11626     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11627     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11628     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11629     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11630     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11631     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11632
11633     /* Setup the depth/stencil surface. */
11634     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11635     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11636
11637     hr = IDirect3DDevice9_BeginScene(device);
11638     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11639     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11640     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11641     hr = IDirect3DDevice9_EndScene(device);
11642     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11643
11644     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11645     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11646     IDirect3DSurface9_Release(ds);
11647     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11648     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11649     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11650     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11651     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11652     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11653
11654     /* Read the depth values back. */
11655     hr = IDirect3DDevice9_BeginScene(device);
11656     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11657     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11658     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11659     hr = IDirect3DDevice9_EndScene(device);
11660     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11661
11662     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11663     {
11664         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11665         ok(color_match(color, expected_colors[i].color, 1),
11666                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11667                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11668     }
11669
11670     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11671     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11672
11673     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11674     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11675     IDirect3DSurface9_Release(original_ds);
11676     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11677     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11678     IDirect3DTexture9_Release(texture);
11679     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11680     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11681     IDirect3DPixelShader9_Release(ps);
11682
11683     IDirect3DSurface9_Release(original_rt);
11684     IDirect3DSurface9_Release(rt);
11685 }
11686
11687 static void shadow_test(IDirect3DDevice9 *device)
11688 {
11689     static const DWORD ps_code[] =
11690     {
11691         0xffff0200,                                                             /* ps_2_0                       */
11692         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11693         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11694         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11695         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11696         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11697         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11698         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11699         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11700         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11701         0x0000ffff,                                                             /* end                          */
11702     };
11703     struct
11704     {
11705         D3DFORMAT format;
11706         const char *name;
11707     }
11708     formats[] =
11709     {
11710         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
11711         {D3DFMT_D32,            "D3DFMT_D32"},
11712         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
11713         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
11714         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
11715         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
11716         {D3DFMT_D16,            "D3DFMT_D16"},
11717         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
11718         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
11719     };
11720     struct
11721     {
11722         float x, y, z;
11723         float s, t, p, q;
11724     }
11725     quad[] =
11726     {
11727         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11728         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11729         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11730         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11731     };
11732     struct
11733     {
11734         UINT x, y;
11735         D3DCOLOR color;
11736     }
11737     expected_colors[] =
11738     {
11739         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11740         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11741         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11742         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11743         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11744         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11745         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11746         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11747     };
11748
11749     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11750     IDirect3DPixelShader9 *ps;
11751     IDirect3D9 *d3d9;
11752     D3DCAPS9 caps;
11753     HRESULT hr;
11754     UINT i;
11755
11756     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11757     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11758     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11759     {
11760         skip("No pixel shader 2.0 support, skipping shadow test.\n");
11761         return;
11762     }
11763
11764     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11765     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11766     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11767     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11768     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11769     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11770
11771     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11772             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11773     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11774     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11775     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11776
11777     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11778     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11779     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11780     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11781     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11782     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11783     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11784     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11785     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11786     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11787
11788     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11789     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11790     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11791     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11792     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11793     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11794     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11795     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11796     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11797     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11798
11799     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11800     {
11801         D3DFORMAT format = formats[i].format;
11802         IDirect3DTexture9 *texture;
11803         IDirect3DSurface9 *ds;
11804         unsigned int j;
11805
11806         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11807                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11808         if (FAILED(hr)) continue;
11809
11810         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11811                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11812         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11813
11814         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11815         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11816
11817         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11818         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11819
11820         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11821         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11822
11823         IDirect3DDevice9_SetPixelShader(device, NULL);
11824         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11825
11826         /* Setup the depth/stencil surface. */
11827         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11828         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11829
11830         hr = IDirect3DDevice9_BeginScene(device);
11831         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11832         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11833         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11834         hr = IDirect3DDevice9_EndScene(device);
11835         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11836
11837         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11838         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11839         IDirect3DSurface9_Release(ds);
11840
11841         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11842         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11843
11844         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11845         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11846
11847         hr = IDirect3DDevice9_SetPixelShader(device, ps);
11848         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11849
11850         /* Do the actual shadow mapping. */
11851         hr = IDirect3DDevice9_BeginScene(device);
11852         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11853         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11854         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11855         hr = IDirect3DDevice9_EndScene(device);
11856         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11857
11858         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11859         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11860         IDirect3DTexture9_Release(texture);
11861
11862         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11863         {
11864             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11865             ok(color_match(color, expected_colors[j].color, 0),
11866                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11867                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11868                     formats[i].name, color);
11869         }
11870
11871         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11872         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11873     }
11874
11875     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11876     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11877     IDirect3DPixelShader9_Release(ps);
11878
11879     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11880     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11881     IDirect3DSurface9_Release(original_ds);
11882
11883     IDirect3DSurface9_Release(original_rt);
11884     IDirect3DSurface9_Release(rt);
11885
11886     IDirect3D9_Release(d3d9);
11887 }
11888
11889 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
11890 {
11891     const struct vertex quad1[] =
11892     {
11893         {-1.0f, -1.0f, 0.0f, 0xfff9e814},
11894         { 1.0f, -1.0f, 0.0f, 0xfff9e814},
11895         {-1.0f,  1.0f, 0.0f, 0xfff9e814},
11896         { 1.0f,  1.0f, 0.0f, 0xfff9e814},
11897     };
11898     const struct vertex quad2[] =
11899     {
11900         {-1.0f, -1.0f, 0.0f, 0xff002b7f},
11901         { 1.0f, -1.0f, 0.0f, 0xff002b7f},
11902         {-1.0f,  1.0f, 0.0f, 0xff002b7f},
11903         { 1.0f,  1.0f, 0.0f, 0xff002b7f},
11904     };
11905     D3DCOLOR color;
11906     HRESULT hr;
11907
11908     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
11909     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11910
11911     hr = IDirect3DDevice9_BeginScene(device);
11912     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11913
11914     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11915     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11916
11917     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11918     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11919     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11920     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11921
11922     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
11923     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11924     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11925     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11926
11927     hr = IDirect3DDevice9_EndScene(device);
11928     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11929
11930     color = getPixelColor(device, 1, 240);
11931     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11932     color = getPixelColor(device, 638, 240);
11933     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11934
11935     color = getPixelColor(device, 1, 241);
11936     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11937     color = getPixelColor(device, 638, 241);
11938     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11939 }
11940
11941 static void clip_planes_test(IDirect3DDevice9 *device)
11942 {
11943     const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
11944
11945     const DWORD shader_code[] = {
11946         0xfffe0200, /* vs_2_0 */
11947         0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11948         0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11949         0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11950         0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11951         0x0000ffff /* end */
11952     };
11953     IDirect3DVertexShader9 *shader;
11954
11955     IDirect3DTexture9 *offscreen = NULL;
11956     IDirect3DSurface9 *offscreen_surface, *original_rt;
11957     HRESULT hr;
11958
11959     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11960     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11961
11962     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11963     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11964     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
11965     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11966     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11967     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11968     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11969     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11970
11971     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11972     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
11973     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11974     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
11975
11976     IDirect3DDevice9_SetClipPlane(device, 0, plane0);
11977
11978     clip_planes(device, "Onscreen FFP");
11979
11980     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
11981     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11982     hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
11983     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11984     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11985     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11986
11987     clip_planes(device, "Offscreen FFP");
11988
11989     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11990     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11991
11992     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11993     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
11994     IDirect3DDevice9_SetVertexShader(device, shader);
11995     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
11996
11997     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11998     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11999
12000     clip_planes(device, "Onscreen vertex shader");
12001
12002     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
12003     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12004
12005     clip_planes(device, "Offscreen vertex shader");
12006
12007     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12008     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12009
12010     IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
12011     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12012     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
12013     IDirect3DVertexShader9_Release(shader);
12014     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12015     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
12016     IDirect3DSurface9_Release(original_rt);
12017     IDirect3DSurface9_Release(offscreen_surface);
12018     IDirect3DTexture9_Release(offscreen);
12019 }
12020
12021 static void fp_special_test(IDirect3DDevice9 *device)
12022 {
12023     static const DWORD vs_header[] =
12024     {
12025         0xfffe0200,                                                             /* vs_2_0                       */
12026         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
12027         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
12028         0x0200001f, 0x80000005, 0x900f0001,                                     /* dcl_texcoord0 v1             */
12029     };
12030
12031     static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001};         /* log r0.x, v1.x               */
12032     static const DWORD vs_pow[] =
12033             {0x03000020, 0x80010000, 0x90000001, 0x90000001};                   /* pow r0.x, v1.x, v1.x         */
12034     static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001};         /* nrm r0.xyz, v1.x             */
12035     static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001};        /* rcp r0.x, v1.x               */
12036     static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001};        /* rcp r0.x, -v1.x              */
12037     static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001};        /* rsq r0.x, v1.x               */
12038     static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001};        /* rsq r0.x, -v1.x              */
12039     static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001,          /* lit r0, v1.xxxx              */
12040             0x02000001, 0x80010000, 0x80aa0000};                                /* mov r0.x, v0.z               */
12041
12042     static const DWORD vs_footer[] =
12043     {
12044         0x03000005, 0x80020000, 0x80000000, 0xa0ff0000,                         /* mul r0.y, r0.x, c0.w         */
12045         0x0300000d, 0x80040000, 0x80000000, 0x80550000,                         /* sge r0.z, r0.x, r0.y         */
12046         0x0300000d, 0x80020000, 0x80e40000, 0x80000000,                         /* sge r0.y, r0, r0.x           */
12047         0x03000005, 0x80040000, 0x80550000, 0x80e40000,                         /* mul r0.z, r0.y, r0           */
12048         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
12049         0x0300000c, 0x80020000, 0x80000000, 0x80000000,                         /* slt r0.y, r0.x, r0.x         */
12050         0x03000002, 0x80040000, 0x80550000, 0x80550000,                         /* add r0.z, r0.y, r0.y         */
12051         0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000,                         /* slt r0.y, c0.x, r0.w         */
12052         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
12053         0x03000002, 0x80040000, 0x81550000, 0xa0e40000,                         /* add r0.z, -r0.y, c0          */
12054         0x0300000c, 0x80080000, 0xa0000000, 0x80e40000,                         /* slt r0.w, c0.x, r0           */
12055         0x03000005, 0x80040000, 0x80ff0000, 0x80e40000,                         /* mul r0.z, r0.w, r0           */
12056         0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000,             /* mad r0.y, r0.z, c0, r0       */
12057         0x02000001, 0xe0030000, 0x80e40000,                                     /* mov oT0.xy, r0               */
12058         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
12059         0x0000ffff,                                                             /* end                          */
12060     };
12061
12062     static const struct
12063     {
12064         const char *name;
12065         const DWORD *ops;
12066         DWORD size;
12067         D3DCOLOR r600;
12068         D3DCOLOR nv40;
12069         D3DCOLOR nv50;
12070     }
12071     vs_body[] =
12072     {
12073         /* The basic ideas here are:
12074          *     2.0 * +/-INF == +/-INF
12075          *     NAN != NAN
12076          *
12077          * The vertex shader value is written to the red component, with 0.0
12078          * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
12079          * result in 0x00. The pixel shader value is written to the green
12080          * component, but here 0.0 also results in 0x00. The actual value is
12081          * written to the blue component.
12082          *
12083          * There are considerable differences between graphics cards in how
12084          * these are handled, but pow and nrm never generate INF or NAN. */
12085         {"log",     vs_log,     sizeof(vs_log),     0x00000000, 0x00ff0000, 0x00ff7f00},
12086         {"pow",     vs_pow,     sizeof(vs_pow),     0x000000ff, 0x0000ff00, 0x000000ff},
12087         {"nrm",     vs_nrm,     sizeof(vs_nrm),     0x00ff0000, 0x0000ff00, 0x00ff0000},
12088         {"rcp1",    vs_rcp1,    sizeof(vs_rcp1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12089         {"rcp2",    vs_rcp2,    sizeof(vs_rcp2),    0x00000000, 0x00ff0000, 0x00ff7f00},
12090         {"rsq1",    vs_rsq1,    sizeof(vs_rsq1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12091         {"rsq2",    vs_rsq2,    sizeof(vs_rsq2),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
12092         {"lit",     vs_lit,     sizeof(vs_lit),     0x00ff0000, 0x00ff0000, 0x00ff0000},
12093     };
12094
12095     static const DWORD ps_code[] =
12096     {
12097         0xffff0200,                                                             /* ps_2_0                       */
12098         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
12099         0x0200001f, 0x80000000, 0xb0030000,                                     /* dcl t0.xy                    */
12100         0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000,                         /* max r1.x, t0, c0             */
12101         0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000,                         /* min r0.x, t0, c0             */
12102         0x03000002, 0x80010000, 0x80e40000, 0x81e40001,                         /* add r0.x, r0, -r1            */
12103         0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000,             /* mad r1.x, t0, c0.w. -t0      */
12104         0x02000023, 0x80010002, 0x80e40001,                                     /* abs r2.x, r1                 */
12105         0x02000023, 0x80010000, 0x80e40000,                                     /* abs r0.x, r0                 */
12106         0x02000023, 0x80010001, 0xb0e40000,                                     /* abs r1.x, t0                 */
12107         0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r2, c0.z, c0      */
12108         0x02000023, 0x80010002, 0x80e40002,                                     /* abs r2.x, r2                 */
12109         0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r1.x, -r1, c0.z, c0      */
12110         0x02000023, 0x80010001, 0x80e40001,                                     /* abs r1.x, r1                 */
12111         0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r3.x, -r2, c0.z, c0      */
12112         0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r1, c0.z, c0      */
12113         0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000,             /* cmp r0.x, -r0, c0.y, c0      */
12114         0x03000005, 0x80010002, 0x80e40002, 0x80e40003,                         /* mul r2.x, r2, r3             */
12115         0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000,             /* cmp r0.x, -r2, c0.z, r0      */
12116         0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000,             /* cmp r0.y, -r1.x, r0.x, c0.x  */
12117         0x02000001, 0x80050000, 0xb0c90000,                                     /* mov r0.xz, t0.yzxw           */
12118         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.w, c0.z               */
12119         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
12120         0x0000ffff,                                                             /* end                          */
12121     };
12122
12123     struct
12124     {
12125         float x, y, z;
12126         float s;
12127     }
12128     quad[] =
12129     {
12130         { -1.0f,  1.0f, 0.0f, 0.0f},
12131         {  1.0f,  1.0f, 1.0f, 0.0f},
12132         { -1.0f, -1.0f, 0.0f, 0.0f},
12133         {  1.0f, -1.0f, 1.0f, 0.0f},
12134     };
12135
12136     IDirect3DPixelShader9 *ps;
12137     UINT body_size = 0;
12138     DWORD *vs_code;
12139     D3DCAPS9 caps;
12140     HRESULT hr;
12141     UINT i;
12142
12143     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12144     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12145     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12146     {
12147         skip("No shader model 2.0 support, skipping floating point specials test.\n");
12148         return;
12149     }
12150
12151     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
12152     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12153
12154     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12155     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
12156     IDirect3DDevice9_SetPixelShader(device, ps);
12157     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12158
12159     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12160     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12161
12162     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
12163     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12164
12165     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12166     {
12167         if (vs_body[i].size > body_size) body_size = vs_body[i].size;
12168     }
12169
12170     vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
12171     memcpy(vs_code, vs_header, sizeof(vs_header));
12172
12173     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
12174     {
12175         DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
12176         IDirect3DVertexShader9 *vs;
12177         D3DCOLOR color;
12178
12179         memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
12180         offset += vs_body[i].size / sizeof(*vs_body[i].ops);
12181         memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
12182
12183         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
12184         ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
12185         IDirect3DDevice9_SetVertexShader(device, vs);
12186         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12187
12188         hr = IDirect3DDevice9_BeginScene(device);
12189         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12190         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12191         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12192         hr = IDirect3DDevice9_EndScene(device);
12193         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12194
12195         color = getPixelColor(device, 320, 240);
12196         ok(color_match(color, vs_body[i].r600, 1)
12197                 || color_match(color, vs_body[i].nv40, 1)
12198                 || color_match(color, vs_body[i].nv50, 1),
12199                 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
12200                 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
12201
12202         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12203         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12204
12205         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12206         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
12207         IDirect3DVertexShader9_Release(vs);
12208     }
12209
12210     HeapFree(GetProcessHeap(), 0, vs_code);
12211
12212     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12213     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
12214     IDirect3DPixelShader9_Release(ps);
12215 }
12216
12217 static void srgbwrite_format_test(IDirect3DDevice9 *device)
12218 {
12219     IDirect3D9 *d3d;
12220     IDirect3DSurface9 *rt, *backbuffer;
12221     IDirect3DTexture9 *texture;
12222     HRESULT hr;
12223     int i;
12224     DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
12225     static const struct
12226     {
12227         D3DFORMAT fmt;
12228         const char *name;
12229     }
12230     formats[] =
12231     {
12232         { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
12233         { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
12234         { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
12235         { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
12236         { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
12237     };
12238     static const struct
12239     {
12240         float x, y, z;
12241         float u, v;
12242     }
12243     quad[] =
12244     {
12245         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12246         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12247         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12248         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12249     };
12250
12251     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12252     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12253     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12254     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12255     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
12256     ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
12257     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12258     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12259     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12260     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12261
12262     for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
12263     {
12264         if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12265                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
12266         {
12267             skip("Format %s not supported as render target, skipping test.\n",
12268                     formats[i].name);
12269             continue;
12270         }
12271
12272         hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
12273                                             D3DPOOL_DEFAULT, &texture, NULL);
12274         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
12275         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
12276         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12277
12278         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
12279         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
12280         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12281         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12282         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
12283         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12284
12285         hr = IDirect3DDevice9_BeginScene(device);
12286         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12287         if(SUCCEEDED(hr))
12288         {
12289             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
12290             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12291             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
12292             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12293             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12294             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12295
12296             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
12297             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12298             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12299             ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12300             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
12301             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12302             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12303             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12304             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12305             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
12306             hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12307             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12308
12309             hr = IDirect3DDevice9_EndScene(device);
12310             ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12311         }
12312
12313         IDirect3DSurface9_Release(rt);
12314         IDirect3DTexture9_Release(texture);
12315
12316         color = getPixelColor(device, 360, 240);
12317         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12318                                     D3DUSAGE_QUERY_SRGBWRITE,
12319                                     D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
12320         {
12321             /* Big slop for R5G6B5 */
12322             ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
12323                 formats[i].name, color_srgb, color);
12324         }
12325         else
12326         {
12327             /* Big slop for R5G6B5 */
12328             ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
12329                 formats[i].name, color_rgb, color);
12330         }
12331
12332         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12333         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12334     }
12335
12336     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12337     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12338
12339     IDirect3D9_Release(d3d);
12340     IDirect3DSurface9_Release(backbuffer);
12341 }
12342
12343 static void ds_size_test(IDirect3DDevice9 *device)
12344 {
12345     IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
12346     HRESULT hr;
12347     DWORD num_passes;
12348     struct
12349     {
12350         float x, y, z;
12351     }
12352     quad[] =
12353     {
12354         {-1.0,  -1.0,   0.0 },
12355         {-1.0,   1.0,   0.0 },
12356         { 1.0,  -1.0,   0.0 },
12357         { 1.0,   1.0,   0.0 }
12358     };
12359
12360     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
12361     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12362     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
12363     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
12364     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
12365     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
12366
12367     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
12368     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12369     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
12370     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12371     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12372     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12373     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12374     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12375     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12376     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12377     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
12378     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
12379     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12380     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12381     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
12382     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12383     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12384     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12385
12386     /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
12387      * but does not change the surface's contents. */
12388     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
12389     ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
12390     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
12391     ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
12392     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
12393     ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12394
12395     /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
12396
12397     /* Turning on any depth-related state results in a ValidateDevice failure */
12398     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12399     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12400     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12401     ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12402         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12403     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12404     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12405     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12406     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12407     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12408     ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12409         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12410
12411     /* Try to draw with the device in an invalid state */
12412     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12413     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12414     hr = IDirect3DDevice9_BeginScene(device);
12415     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12416     if(SUCCEEDED(hr))
12417     {
12418         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12419         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12420         hr = IDirect3DDevice9_EndScene(device);
12421         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12422
12423         /* Don't check the resulting draw unless we find an app that needs it. On nvidia ValidateDevice
12424          * returns CONFLICTINGRENDERSTATE, so the result is undefined. On AMD d3d seems to assume the
12425          * stored Z buffer value is 0.0 for all pixels, even those that are covered by the depth buffer */
12426     }
12427
12428     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12429     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12430     hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12431     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12432     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12433     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12434
12435     IDirect3DSurface9_Release(readback);
12436     IDirect3DSurface9_Release(ds);
12437     IDirect3DSurface9_Release(rt);
12438     IDirect3DSurface9_Release(old_rt);
12439     IDirect3DSurface9_Release(old_ds);
12440 }
12441
12442 static void unbound_sampler_test(IDirect3DDevice9 *device)
12443 {
12444     HRESULT hr;
12445     IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
12446     IDirect3DSurface9 *rt, *old_rt;
12447     DWORD color;
12448
12449     static const DWORD ps_code[] =
12450     {
12451         0xffff0200,                                     /* ps_2_0           */
12452         0x0200001f, 0x90000000, 0xa00f0800,             /* dcl_2d s0        */
12453         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12454         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12455         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12456         0x0000ffff,                                     /* end              */
12457     };
12458     static const DWORD ps_code_cube[] =
12459     {
12460         0xffff0200,                                     /* ps_2_0           */
12461         0x0200001f, 0x98000000, 0xa00f0800,             /* dcl_cube s0      */
12462         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12463         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12464         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12465         0x0000ffff,                                     /* end              */
12466     };
12467     static const DWORD ps_code_volume[] =
12468     {
12469         0xffff0200,                                     /* ps_2_0           */
12470         0x0200001f, 0xa0000000, 0xa00f0800,             /* dcl_volume s0    */
12471         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12472         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12473         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12474         0x0000ffff,                                     /* end              */
12475     };
12476
12477     static const struct
12478     {
12479         float x, y, z;
12480         float u, v;
12481     }
12482     quad[] =
12483     {
12484         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12485         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12486         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12487         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12488     };
12489
12490     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12491     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
12492
12493     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12494     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12495     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
12496     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12497     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
12498     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12499
12500     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
12501     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12502
12503     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12504     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12505
12506     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12507     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12508
12509     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
12510     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12511
12512     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
12513     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
12514
12515     hr = IDirect3DDevice9_SetPixelShader(device, ps);
12516     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12517
12518     hr = IDirect3DDevice9_BeginScene(device);
12519     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12520     if(SUCCEEDED(hr))
12521     {
12522         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12523         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12524
12525         hr = IDirect3DDevice9_EndScene(device);
12526         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12527     }
12528
12529     color = getPixelColorFromSurface(rt, 32, 32);
12530     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12531
12532     /* Now try with a cube texture */
12533     hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
12534     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12535
12536     hr = IDirect3DDevice9_BeginScene(device);
12537     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12538     if (SUCCEEDED(hr))
12539     {
12540         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12541         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12542
12543         hr = IDirect3DDevice9_EndScene(device);
12544         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12545     }
12546
12547     color = getPixelColorFromSurface(rt, 32, 32);
12548     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12549
12550     /* And then with a volume texture */
12551     hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
12552     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12553
12554     hr = IDirect3DDevice9_BeginScene(device);
12555     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12556     if (SUCCEEDED(hr))
12557     {
12558         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12559         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12560
12561         hr = IDirect3DDevice9_EndScene(device);
12562         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12563     }
12564
12565     color = getPixelColorFromSurface(rt, 32, 32);
12566     ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12567
12568     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12569     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12570
12571     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12572     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12573
12574     IDirect3DSurface9_Release(rt);
12575     IDirect3DSurface9_Release(old_rt);
12576     IDirect3DPixelShader9_Release(ps);
12577     IDirect3DPixelShader9_Release(ps_cube);
12578     IDirect3DPixelShader9_Release(ps_volume);
12579 }
12580
12581 static void update_surface_test(IDirect3DDevice9 *device)
12582 {
12583     static const BYTE blocks[][8] =
12584     {
12585         {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
12586         {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
12587         {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
12588         {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
12589         {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
12590         {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
12591         {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
12592     };
12593     static const struct
12594     {
12595         UINT x, y;
12596         D3DCOLOR color;
12597     }
12598     expected_colors[] =
12599     {
12600         { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
12601         { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
12602         {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
12603         {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12604         {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12605         {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12606         {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
12607     };
12608     static const struct
12609     {
12610         float x, y, z, w;
12611         float u, v;
12612     }
12613     tri[] =
12614     {
12615         {  0.0f, 480.0f, 0.0f,  1.0f,   0.0f, 0.0f},
12616         {  0.0f,   0.0f, 0.0f,  1.0f,   0.0f, 1.0f},
12617         {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
12618     };
12619     static const RECT rect_2x2 = {0, 0, 2, 2};
12620     static const struct
12621     {
12622         UINT src_level;
12623         UINT dst_level;
12624         const RECT *r;
12625         HRESULT hr;
12626     }
12627     block_size_tests[] =
12628     {
12629         {1, 0, NULL,      D3D_OK},
12630         {0, 1, NULL,      D3DERR_INVALIDCALL},
12631         {5, 4, NULL,      D3DERR_INVALIDCALL},
12632         {4, 5, NULL,      D3DERR_INVALIDCALL},
12633         {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
12634         {5, 5, &rect_2x2, D3D_OK},
12635     };
12636
12637     IDirect3DSurface9 *src_surface, *dst_surface;
12638     IDirect3DTexture9 *src_tex, *dst_tex;
12639     IDirect3D9 *d3d;
12640     UINT count, i;
12641     HRESULT hr;
12642
12643     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12644     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12645
12646     hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12647             D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
12648     IDirect3D9_Release(d3d);
12649     if (FAILED(hr))
12650     {
12651         skip("DXT1 not supported, skipping test.\n");
12652         return;
12653     }
12654
12655     IDirect3D9_Release(d3d);
12656
12657     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
12658     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12659     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
12660     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12661
12662     count = IDirect3DTexture9_GetLevelCount(src_tex);
12663     ok(count == 7, "Got level count %u, expected 7.\n", count);
12664
12665     for (i = 0; i < count; ++i)
12666     {
12667         UINT row_count, block_count, x, y;
12668         D3DSURFACE_DESC desc;
12669         BYTE *row, *block;
12670         D3DLOCKED_RECT r;
12671
12672         hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
12673         ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
12674
12675         hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
12676         ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
12677
12678         row_count = ((desc.Height + 3) & ~3) / 4;
12679         block_count = ((desc.Width + 3) & ~3) / 4;
12680         row = r.pBits;
12681
12682         for (y = 0; y < row_count; ++y)
12683         {
12684             block = row;
12685             for (x = 0; x < block_count; ++x)
12686             {
12687                 memcpy(block, blocks[i], sizeof(blocks[i]));
12688                 block += sizeof(blocks[i]);
12689             }
12690             row += r.Pitch;
12691         }
12692
12693         hr = IDirect3DTexture9_UnlockRect(src_tex, i);
12694         ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
12695     }
12696
12697     for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
12698     {
12699         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
12700         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12701         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
12702         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12703
12704         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
12705         ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
12706                 hr, i, block_size_tests[i].hr);
12707
12708         IDirect3DSurface9_Release(dst_surface);
12709         IDirect3DSurface9_Release(src_surface);
12710     }
12711
12712     for (i = 0; i < count; ++i)
12713     {
12714         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
12715         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12716         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
12717         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12718
12719         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
12720         ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
12721
12722         IDirect3DSurface9_Release(dst_surface);
12723         IDirect3DSurface9_Release(src_surface);
12724     }
12725
12726     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12727     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12728     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12729     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12730     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
12731     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12732     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
12733     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12734     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12735     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12736     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12737     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12738
12739     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
12740     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12741
12742     hr = IDirect3DDevice9_BeginScene(device);
12743     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12744     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
12745     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12746     hr = IDirect3DDevice9_EndScene(device);
12747     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12748
12749     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
12750     {
12751         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
12752         ok(color_match(color, expected_colors[i].color, 0),
12753                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
12754                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
12755     }
12756
12757     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12758     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12759
12760     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12761     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12762     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12763     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12764     IDirect3DTexture9_Release(dst_tex);
12765     IDirect3DTexture9_Release(src_tex);
12766 }
12767
12768 static void multisample_get_rtdata_test(IDirect3DDevice9 *device)
12769 {
12770     IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
12771     IDirect3D9 *d3d9;
12772     HRESULT hr;
12773
12774     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
12775     ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
12776     hr = IDirect3D9_CheckDeviceMultiSampleType(d3d9, D3DADAPTER_DEFAULT,
12777             D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
12778     IDirect3D9_Release(d3d9);
12779     if (FAILED(hr))
12780     {
12781         skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
12782         return;
12783     }
12784
12785     hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
12786             D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
12787     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
12788     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
12789             D3DPOOL_SYSTEMMEM, &readback, NULL);
12790     ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
12791
12792     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
12793     ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
12794     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
12795     ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
12796
12797     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12798     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
12799     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
12800     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
12801
12802     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
12803     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
12804     hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
12805     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
12806
12807     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
12808     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
12809     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
12810     ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
12811
12812     IDirect3DSurface9_Release(original_ds);
12813     IDirect3DSurface9_Release(original_rt);
12814     IDirect3DSurface9_Release(readback);
12815     IDirect3DSurface9_Release(rt);
12816 }
12817
12818 START_TEST(visual)
12819 {
12820     IDirect3DDevice9 *device_ptr;
12821     D3DCAPS9 caps;
12822     HRESULT hr;
12823     DWORD color;
12824
12825     d3d9_handle = LoadLibraryA("d3d9.dll");
12826     if (!d3d9_handle)
12827     {
12828         skip("Could not load d3d9.dll\n");
12829         return;
12830     }
12831
12832     device_ptr = init_d3d9();
12833     if (!device_ptr)
12834     {
12835         skip("Creating the device failed\n");
12836         return;
12837     }
12838
12839     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
12840
12841     /* Check for the reliability of the returned data */
12842     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
12843     if(FAILED(hr))
12844     {
12845         skip("Clear failed, can't assure correctness of the test results, skipping\n");
12846         goto cleanup;
12847     }
12848
12849     color = getPixelColor(device_ptr, 1, 1);
12850     if(color !=0x00ff0000)
12851     {
12852         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12853         goto cleanup;
12854     }
12855     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12856
12857     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
12858     if(FAILED(hr))
12859     {
12860         skip("Clear failed, can't assure correctness of the test results, skipping\n");
12861         goto cleanup;
12862     }
12863
12864     color = getPixelColor(device_ptr, 639, 479);
12865     if(color != 0x0000ddee)
12866     {
12867         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12868         goto cleanup;
12869     }
12870     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12871
12872     /* Now execute the real tests */
12873     depth_clamp_test(device_ptr);
12874     stretchrect_test(device_ptr);
12875     lighting_test(device_ptr);
12876     clear_test(device_ptr);
12877     color_fill_test(device_ptr);
12878     fog_test(device_ptr);
12879     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
12880     {
12881         test_cube_wrap(device_ptr);
12882     } else {
12883         skip("No cube texture support\n");
12884     }
12885     z_range_test(device_ptr);
12886     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
12887     {
12888         maxmip_test(device_ptr);
12889     }
12890     else
12891     {
12892         skip("No mipmap support\n");
12893     }
12894     offscreen_test(device_ptr);
12895     ds_size_test(device_ptr);
12896     alpha_test(device_ptr);
12897     shademode_test(device_ptr);
12898     srgbtexture_test(device_ptr);
12899     release_buffer_test(device_ptr);
12900     float_texture_test(device_ptr);
12901     g16r16_texture_test(device_ptr);
12902     pixelshader_blending_test(device_ptr);
12903     texture_transform_flags_test(device_ptr);
12904     autogen_mipmap_test(device_ptr);
12905     fixed_function_decl_test(device_ptr);
12906     conditional_np2_repeat_test(device_ptr);
12907     fixed_function_bumpmap_test(device_ptr);
12908     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
12909         stencil_cull_test(device_ptr);
12910     } else {
12911         skip("No two sided stencil support\n");
12912     }
12913     pointsize_test(device_ptr);
12914     tssargtemp_test(device_ptr);
12915     np2_stretch_rect_test(device_ptr);
12916     yuv_color_test(device_ptr);
12917     zwriteenable_test(device_ptr);
12918     alphatest_test(device_ptr);
12919     viewport_test(device_ptr);
12920
12921     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
12922     {
12923         test_constant_clamp_vs(device_ptr);
12924         test_compare_instructions(device_ptr);
12925     }
12926     else skip("No vs_1_1 support\n");
12927
12928     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
12929     {
12930         test_mova(device_ptr);
12931         loop_index_test(device_ptr);
12932         sincos_test(device_ptr);
12933         sgn_test(device_ptr);
12934         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12935             test_vshader_input(device_ptr);
12936             test_vshader_float16(device_ptr);
12937             stream_test(device_ptr);
12938         } else {
12939             skip("No vs_3_0 support\n");
12940         }
12941     }
12942     else skip("No vs_2_0 support\n");
12943
12944     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12945     {
12946         fog_with_shader_test(device_ptr);
12947     }
12948     else skip("No vs_1_1 and ps_1_1 support\n");
12949
12950     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12951     {
12952         texbem_test(device_ptr);
12953         texdepth_test(device_ptr);
12954         texkill_test(device_ptr);
12955         x8l8v8u8_test(device_ptr);
12956         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
12957             constant_clamp_ps_test(device_ptr);
12958             cnd_test(device_ptr);
12959             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
12960                 dp2add_ps_test(device_ptr);
12961                 unbound_sampler_test(device_ptr);
12962                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12963                     nested_loop_test(device_ptr);
12964                     pretransformed_varying_test(device_ptr);
12965                     vFace_register_test(device_ptr);
12966                     vpos_register_test(device_ptr);
12967                     multiple_rendertargets_test(device_ptr);
12968                 } else {
12969                     skip("No ps_3_0 or vs_3_0 support\n");
12970                 }
12971             } else {
12972                 skip("No ps_2_0 support\n");
12973             }
12974         }
12975     }
12976     else skip("No ps_1_1 support\n");
12977
12978     texop_test(device_ptr);
12979     texop_range_test(device_ptr);
12980     alphareplicate_test(device_ptr);
12981     dp3_alpha_test(device_ptr);
12982     depth_buffer_test(device_ptr);
12983     depth_buffer2_test(device_ptr);
12984     depth_blit_test(device_ptr);
12985     intz_test(device_ptr);
12986     shadow_test(device_ptr);
12987     fp_special_test(device_ptr);
12988     depth_bounds_test(device_ptr);
12989     srgbwrite_format_test(device_ptr);
12990     clip_planes_test(device_ptr);
12991     update_surface_test(device_ptr);
12992     multisample_get_rtdata_test(device_ptr);
12993
12994 cleanup:
12995     if(device_ptr) {
12996         D3DPRESENT_PARAMETERS present_parameters;
12997         IDirect3DSwapChain9 *swapchain;
12998         ULONG ref;
12999
13000         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
13001         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
13002         IDirect3DSwapChain9_Release(swapchain);
13003         ref = IDirect3DDevice9_Release(device_ptr);
13004         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
13005         DestroyWindow(present_parameters.hDeviceWindow);
13006     }
13007 }