dinput: SetActionMap setting the device buffer.
[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         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
239     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
240                       0.0f, 1.0f, 0.0f, 0.0f,
241                       0.0f, 0.0f, 1.0f, 0.0f,
242                       0.0f, 0.0f, 0.0f, 1.0f };
243
244     struct vertex unlitquad[] =
245     {
246         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
247         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
248         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
249         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
250     };
251     struct vertex litquad[] =
252     {
253         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
254         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
255         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
256         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
257     };
258     struct nvertex unlitnquad[] =
259     {
260         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
261         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
262         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
263         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
264     };
265     struct nvertex litnquad[] =
266     {
267         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
268         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
269         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
270         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
271     };
272     WORD Indices[] = {0, 1, 2, 2, 3, 0};
273
274     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
275     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
276
277     /* Setup some states that may cause issues */
278     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
279     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
280     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
281     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
282     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
283     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
284     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
285     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
286     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
287     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
288     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
289     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
291     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
292     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
293     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
294     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
295     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
296     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
297     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
298     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
299     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
300     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
301     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
302
303     hr = IDirect3DDevice9_SetFVF(device, 0);
304     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
305
306     hr = IDirect3DDevice9_SetFVF(device, fvf);
307     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
308
309     hr = IDirect3DDevice9_BeginScene(device);
310     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
311     if(hr == D3D_OK)
312     {
313         /* No lights are defined... That means, lit vertices should be entirely black */
314         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
315         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
316         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
317                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
318         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
319
320         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
321         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
322         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
323                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
324         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
325
326         hr = IDirect3DDevice9_SetFVF(device, nfvf);
327         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
328
329         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
330         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
331         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
332                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
333         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
334
335         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
336         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
337         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
338                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
339         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
340
341         IDirect3DDevice9_EndScene(device);
342         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
343     }
344
345     color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
346     ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
347     color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
348     ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
349     color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
350     ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
351     color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
352     ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
353
354     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
355
356     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
357     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
358     memset(&material, 0, sizeof(material));
359     material.Diffuse.r = 0.0;
360     material.Diffuse.g = 0.0;
361     material.Diffuse.b = 0.0;
362     material.Diffuse.a = 1.0;
363     material.Ambient.r = 0.0;
364     material.Ambient.g = 0.0;
365     material.Ambient.b = 0.0;
366     material.Ambient.a = 0.0;
367     material.Specular.r = 0.0;
368     material.Specular.g = 0.0;
369     material.Specular.b = 0.0;
370     material.Specular.a = 0.0;
371     material.Emissive.r = 0.0;
372     material.Emissive.g = 0.0;
373     material.Emissive.b = 0.0;
374     material.Emissive.a = 0.0;
375     material.Power = 0.0;
376     IDirect3DDevice9_SetMaterial(device, &material);
377     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
378
379     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
380     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
381     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
382     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
383
384     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
385     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
386     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
387     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
388     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
389     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
390     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
391     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
392
393     hr = IDirect3DDevice9_BeginScene(device);
394     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
395     if(SUCCEEDED(hr)) {
396         struct vertex lighting_test[] = {
397             {-1.0,   -1.0,   0.1,    0x8000ff00},
398             { 1.0,   -1.0,   0.1,    0x80000000},
399             {-1.0,    1.0,   0.1,    0x8000ff00},
400             { 1.0,    1.0,   0.1,    0x80000000}
401         };
402         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
403         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
404         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
405         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
406
407         hr = IDirect3DDevice9_EndScene(device);
408         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
409     }
410
411     color = getPixelColor(device, 320, 240);
412     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
413     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
414
415     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
416     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
417     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
418     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
419     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
420     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
421     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
422     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
423     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
424     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
425     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
426     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
427 }
428
429 static void clear_test(IDirect3DDevice9 *device)
430 {
431     /* Tests the correctness of clearing parameters */
432     HRESULT hr;
433     D3DRECT rect[2];
434     D3DRECT rect_negneg;
435     DWORD color;
436     D3DVIEWPORT9 old_vp, vp;
437     RECT scissor;
438     DWORD oldColorWrite;
439     BOOL invalid_clear_failed = FALSE;
440
441     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
442     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
443
444     /* Positive x, negative y */
445     rect[0].x1 = 0;
446     rect[0].y1 = 480;
447     rect[0].x2 = 320;
448     rect[0].y2 = 240;
449
450     /* Positive x, positive y */
451     rect[1].x1 = 0;
452     rect[1].y1 = 0;
453     rect[1].x2 = 320;
454     rect[1].y2 = 240;
455     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
456      * returns D3D_OK, but ignores the rectangle silently
457      */
458     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
459     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
460     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
461
462     /* negative x, negative y */
463     rect_negneg.x1 = 640;
464     rect_negneg.y1 = 240;
465     rect_negneg.x2 = 320;
466     rect_negneg.y2 = 0;
467     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
468     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
469     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
470
471     color = getPixelColor(device, 160, 360); /* lower left quad */
472     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
473     color = getPixelColor(device, 160, 120); /* upper left quad */
474     if(invalid_clear_failed) {
475         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
476         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
477     } else {
478         /* If the negative rectangle was dropped silently, the correct ones are cleared */
479         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
480     }
481     color = getPixelColor(device, 480, 360); /* lower right quad  */
482     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
483     color = getPixelColor(device, 480, 120); /* upper right quad */
484     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
485
486     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
487
488     /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
489      * clear the red quad in the top left part of the render target. For some reason it
490      * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
491      * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
492      * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
493      * pick some obvious value
494      */
495     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
496     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
497
498     /* Test how the viewport affects clears */
499     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
500     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
501     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
502     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
503
504     vp.X = 160;
505     vp.Y = 120;
506     vp.Width = 160;
507     vp.Height = 120;
508     vp.MinZ = 0.0;
509     vp.MaxZ = 1.0;
510     hr = IDirect3DDevice9_SetViewport(device, &vp);
511     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
512     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
513     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
514
515     vp.X = 320;
516     vp.Y = 240;
517     vp.Width = 320;
518     vp.Height = 240;
519     vp.MinZ = 0.0;
520     vp.MaxZ = 1.0;
521     hr = IDirect3DDevice9_SetViewport(device, &vp);
522     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
523     rect[0].x1 = 160;
524     rect[0].y1 = 120;
525     rect[0].x2 = 480;
526     rect[0].y2 = 360;
527     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
528     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
529
530     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
531     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
532
533     color = getPixelColor(device, 158, 118);
534     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
535     color = getPixelColor(device, 162, 118);
536     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
537     color = getPixelColor(device, 158, 122);
538     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
539     color = getPixelColor(device, 162, 122);
540     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
541
542     color = getPixelColor(device, 318, 238);
543     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
544     color = getPixelColor(device, 322, 238);
545     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
546     color = getPixelColor(device, 318, 242);
547     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
548     color = getPixelColor(device, 322, 242);
549     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
550
551     color = getPixelColor(device, 478, 358);
552     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
553     color = getPixelColor(device, 482, 358);
554     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
555     color = getPixelColor(device, 478, 362);
556     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
557     color = getPixelColor(device, 482, 362);
558     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
559
560     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
561
562     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
563     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
564
565     scissor.left = 160;
566     scissor.right = 480;
567     scissor.top = 120;
568     scissor.bottom = 360;
569     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
570     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
571     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
572     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
573
574     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
575     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
576     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
577     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
578
579     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
580     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
581
582     color = getPixelColor(device, 158, 118);
583     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
584     color = getPixelColor(device, 162, 118);
585     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
586     color = getPixelColor(device, 158, 122);
587     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
588     color = getPixelColor(device, 162, 122);
589     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
590
591     color = getPixelColor(device, 158, 358);
592     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
593     color = getPixelColor(device, 162, 358);
594     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
595     color = getPixelColor(device, 158, 358);
596     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
597     color = getPixelColor(device, 162, 362);
598     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
599
600     color = getPixelColor(device, 478, 118);
601     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
602     color = getPixelColor(device, 478, 122);
603     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
604     color = getPixelColor(device, 482, 122);
605     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
606     color = getPixelColor(device, 482, 358);
607     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
608
609     color = getPixelColor(device, 478, 358);
610     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
611     color = getPixelColor(device, 478, 362);
612     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
613     color = getPixelColor(device, 482, 358);
614     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
615     color = getPixelColor(device, 482, 362);
616     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
617
618     color = getPixelColor(device, 318, 238);
619     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
620     color = getPixelColor(device, 318, 242);
621     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
622     color = getPixelColor(device, 322, 238);
623     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
624     color = getPixelColor(device, 322, 242);
625     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
626
627     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
628
629     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
630     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
631     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
632     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
633
634     /* Same nvidia windows driver trouble with white clears as earlier in the same test */
635     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
636     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
637
638     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
639     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
640
641     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
642     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
643
644     /* Colorwriteenable does not affect the clear */
645     color = getPixelColor(device, 320, 240);
646     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
647
648     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
649 }
650
651 static void color_fill_test(IDirect3DDevice9 *device)
652 {
653     HRESULT hr;
654     IDirect3DSurface9 *backbuffer = NULL;
655     IDirect3DSurface9 *rt_surface = NULL;
656     IDirect3DSurface9 *offscreen_surface = NULL;
657     DWORD fill_color, color;
658
659     /* Test ColorFill on a the backbuffer (should pass) */
660     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
661     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
662     if(backbuffer)
663     {
664         fill_color = 0x112233;
665         hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
666         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
667
668         color = getPixelColor(device, 0, 0);
669         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
670
671         IDirect3DSurface9_Release(backbuffer);
672     }
673
674     /* Test ColorFill on a render target surface (should pass) */
675     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
676     ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
677     if(rt_surface)
678     {
679         fill_color = 0x445566;
680         hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
681         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
682
683         color = getPixelColorFromSurface(rt_surface, 0, 0);
684         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
685
686         IDirect3DSurface9_Release(rt_surface);
687     }
688
689     /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
690     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
691             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
692     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
693     if(offscreen_surface)
694     {
695         fill_color = 0x778899;
696         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
697         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
698
699         color = getPixelColorFromSurface(offscreen_surface, 0, 0);
700         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
701
702         IDirect3DSurface9_Release(offscreen_surface);
703     }
704
705     /* Try ColorFill on a offscreen surface in sysmem (should fail) */
706     offscreen_surface = NULL;
707     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
708             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
709     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
710     if(offscreen_surface)
711     {
712         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
713         ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
714
715         IDirect3DSurface9_Release(offscreen_surface);
716     }
717 }
718
719 typedef struct {
720     float in[4];
721     DWORD out;
722 } test_data_t;
723
724 /*
725  *  c7      mova    ARGB            mov     ARGB
726  * -2.4     -2      0x00ffff00      -3      0x00ff0000
727  * -1.6     -2      0x00ffff00      -2      0x00ffff00
728  * -0.4      0      0x0000ffff      -1      0x0000ff00
729  *  0.4      0      0x0000ffff       0      0x0000ffff
730  *  1.6      2      0x00ff00ff       1      0x000000ff
731  *  2.4      2      0x00ff00ff       2      0x00ff00ff
732  */
733 static void test_mova(IDirect3DDevice9 *device)
734 {
735     static const DWORD mova_test[] = {
736         0xfffe0200,                                                             /* vs_2_0                       */
737         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
738         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
739         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
740         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
741         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
742         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
743         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
744         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
745         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
746         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
747         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
748         0x0000ffff                                                              /* END                          */
749     };
750     static const DWORD mov_test[] = {
751         0xfffe0101,                                                             /* vs_1_1                       */
752         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
753         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
754         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
755         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
756         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
757         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
758         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
759         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
760         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
761         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
762         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
763         0x0000ffff                                                              /* END                          */
764     };
765
766     static const test_data_t test_data[2][6] = {
767         {
768             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
769             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
770             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
771             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
772             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
773             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
774         },
775         {
776             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
777             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
778             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
779             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
780             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
781             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
782         }
783     };
784
785     static const float quad[][3] = {
786         {-1.0f, -1.0f, 0.0f},
787         {-1.0f,  1.0f, 0.0f},
788         { 1.0f, -1.0f, 0.0f},
789         { 1.0f,  1.0f, 0.0f},
790     };
791
792     static const D3DVERTEXELEMENT9 decl_elements[] = {
793         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
794         D3DDECL_END()
795     };
796
797     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
798     IDirect3DVertexShader9 *mova_shader = NULL;
799     IDirect3DVertexShader9 *mov_shader = NULL;
800     HRESULT hr;
801     UINT i, j;
802
803     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
804     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
805     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
806     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
807     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
808     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
809     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
810     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
811
812     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
813     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
814     for(j = 0; j < 2; ++j)
815     {
816         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
817         {
818             DWORD color;
819
820             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
821             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
822
823             hr = IDirect3DDevice9_BeginScene(device);
824             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
825
826             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
827             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
828
829             hr = IDirect3DDevice9_EndScene(device);
830             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
831
832             color = getPixelColor(device, 320, 240);
833             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
834                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
835
836             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
837             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
838
839             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
840             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
841         }
842         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
843         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
844     }
845
846     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
847     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
848
849     IDirect3DVertexDeclaration9_Release(vertex_declaration);
850     IDirect3DVertexShader9_Release(mova_shader);
851     IDirect3DVertexShader9_Release(mov_shader);
852 }
853
854 struct sVertex {
855     float x, y, z;
856     DWORD diffuse;
857     DWORD specular;
858 };
859
860 struct sVertexT {
861     float x, y, z, rhw;
862     DWORD diffuse;
863     DWORD specular;
864 };
865
866 static void fog_test(IDirect3DDevice9 *device)
867 {
868     HRESULT hr;
869     D3DCOLOR color;
870     float start = 0.0f, end = 1.0f;
871     D3DCAPS9 caps;
872     int i;
873
874     /* Gets full z based fog with linear fog, no fog with specular color */
875     struct sVertex unstransformed_1[] = {
876         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
877         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
878         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
879         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
880     };
881     /* Ok, I am too lazy to deal with transform matrices */
882     struct sVertex unstransformed_2[] = {
883         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
884         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
885         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
886         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
887     };
888     /* Untransformed ones. Give them a different diffuse color to make the test look
889      * nicer. It also makes making sure that they are drawn correctly easier.
890      */
891     struct sVertexT transformed_1[] = {
892         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
893         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
894         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
895         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
896     };
897     struct sVertexT transformed_2[] = {
898         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
899         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
900         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
901         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
902     };
903     struct vertex rev_fog_quads[] = {
904        {-1.0,   -1.0,   0.1,    0x000000ff},
905        {-1.0,    0.0,   0.1,    0x000000ff},
906        { 0.0,    0.0,   0.1,    0x000000ff},
907        { 0.0,   -1.0,   0.1,    0x000000ff},
908
909        { 0.0,   -1.0,   0.9,    0x000000ff},
910        { 0.0,    0.0,   0.9,    0x000000ff},
911        { 1.0,    0.0,   0.9,    0x000000ff},
912        { 1.0,   -1.0,   0.9,    0x000000ff},
913
914        { 0.0,    0.0,   0.4,    0x000000ff},
915        { 0.0,    1.0,   0.4,    0x000000ff},
916        { 1.0,    1.0,   0.4,    0x000000ff},
917        { 1.0,    0.0,   0.4,    0x000000ff},
918
919        {-1.0,    0.0,   0.7,    0x000000ff},
920        {-1.0,    1.0,   0.7,    0x000000ff},
921        { 0.0,    1.0,   0.7,    0x000000ff},
922        { 0.0,    0.0,   0.7,    0x000000ff},
923     };
924     WORD Indices[] = {0, 1, 2, 2, 3, 0};
925
926     memset(&caps, 0, sizeof(caps));
927     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
928     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
929     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
930     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
931
932     /* Setup initial states: No lighting, fog on, fog color */
933     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
934     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
935     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
936     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
937     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
938     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
939
940     /* First test: Both table fog and vertex fog off */
941     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
942     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
943     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
944     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
945
946     /* Start = 0, end = 1. Should be default, but set them */
947     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
948     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
949     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
950     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
951
952     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
953     {
954         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
955         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
956         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
957         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
958                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
959                                                      sizeof(unstransformed_1[0]));
960         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
961
962         /* That makes it use the Z value */
963         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
964         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
965         /* Untransformed, vertex fog != none (or table fog != none):
966          * Use the Z value as input into the equation
967          */
968         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
969                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
970                                                      sizeof(unstransformed_1[0]));
971         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
972
973         /* transformed verts */
974         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
975         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
976         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
977         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
978                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
979                                                      sizeof(transformed_1[0]));
980         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
981
982         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
983         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
984         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
985          * equation
986          */
987         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
988                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
989                                                      sizeof(transformed_2[0]));
990         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
991
992         hr = IDirect3DDevice9_EndScene(device);
993         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
994     }
995     else
996     {
997         ok(FALSE, "BeginScene failed\n");
998     }
999
1000     color = getPixelColor(device, 160, 360);
1001     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1002     color = getPixelColor(device, 160, 120);
1003     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1004     color = getPixelColor(device, 480, 120);
1005     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1006     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1007     {
1008         color = getPixelColor(device, 480, 360);
1009         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1010     }
1011     else
1012     {
1013         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1014          * The settings above result in no fogging with vertex fog
1015          */
1016         color = getPixelColor(device, 480, 120);
1017         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1018         trace("Info: Table fog not supported by this device\n");
1019     }
1020     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1021
1022     /* Now test the special case fogstart == fogend */
1023     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1024     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1025
1026     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1027     {
1028         start = 512;
1029         end = 512;
1030         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1031         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1032         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1033         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1034
1035         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1036         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1037         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1038         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1039         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1040         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1041
1042         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1043          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1044          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1045          * The third transformed quad remains unfogged because the fogcoords are read from the specular
1046          * color and has fixed fogstart and fogend.
1047          */
1048         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1049                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
1050                 sizeof(unstransformed_1[0]));
1051         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1052         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1053                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
1054                 sizeof(unstransformed_1[0]));
1055         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1056
1057         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1058         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1059         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1060         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1061                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1062                 sizeof(transformed_1[0]));
1063         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1064
1065         hr = IDirect3DDevice9_EndScene(device);
1066         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1067     }
1068     else
1069     {
1070         ok(FALSE, "BeginScene failed\n");
1071     }
1072     color = getPixelColor(device, 160, 360);
1073     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1074     color = getPixelColor(device, 160, 120);
1075     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1076     color = getPixelColor(device, 480, 120);
1077     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1078     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1079
1080     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1081      * but without shaders it seems to work everywhere
1082      */
1083     end = 0.2;
1084     start = 0.8;
1085     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1086     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1087     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1088     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1089     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1090     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1091
1092     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1093      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1094      * so skip this for now
1095      */
1096     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1097         const char *mode = (i ? "table" : "vertex");
1098         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1099         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1100         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1101         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1102         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1103         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1104         hr = IDirect3DDevice9_BeginScene(device);
1105         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1106         if(SUCCEEDED(hr)) {
1107             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1108                                 4,  5,  6,  6,  7, 4,
1109                                 8,  9, 10, 10, 11, 8,
1110                             12, 13, 14, 14, 15, 12};
1111
1112             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1113                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1114                     sizeof(rev_fog_quads[0]));
1115             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1116
1117             hr = IDirect3DDevice9_EndScene(device);
1118             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1119         }
1120         color = getPixelColor(device, 160, 360);
1121         ok(color_match(color, 0x0000ff00, 1),
1122                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1123
1124         color = getPixelColor(device, 160, 120);
1125         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1126                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1127
1128         color = getPixelColor(device, 480, 120);
1129         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1130                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1131
1132         color = getPixelColor(device, 480, 360);
1133         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1134
1135         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1136
1137         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1138             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1139             break;
1140         }
1141     }
1142     /* Turn off the fog master switch to avoid confusing other tests */
1143     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1144     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1145     start = 0.0;
1146     end = 1.0;
1147     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1148     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1149     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1150     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1151     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1152     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1153     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1154     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1155 }
1156
1157 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1158  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1159  * regardless of the actual addressing mode set. The way this test works is
1160  * that we sample in one of the corners of the cubemap with filtering enabled,
1161  * and check the interpolated color. There are essentially two reasonable
1162  * things an implementation can do: Either pick one of the faces and
1163  * interpolate the edge texel with itself (i.e., clamp within the face), or
1164  * interpolate between the edge texels of the three involved faces. It should
1165  * never involve the border color or the other side (texcoord wrapping) of a
1166  * face in the interpolation. */
1167 static void test_cube_wrap(IDirect3DDevice9 *device)
1168 {
1169     static const float quad[][6] = {
1170         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1171         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1172         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1173         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1174     };
1175
1176     static const D3DVERTEXELEMENT9 decl_elements[] = {
1177         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1178         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1179         D3DDECL_END()
1180     };
1181
1182     static const struct {
1183         D3DTEXTUREADDRESS mode;
1184         const char *name;
1185     } address_modes[] = {
1186         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1187         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1188         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1189         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1190         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1191     };
1192
1193     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1194     IDirect3DCubeTexture9 *texture = NULL;
1195     IDirect3DSurface9 *surface = NULL;
1196     IDirect3DSurface9 *face_surface;
1197     D3DLOCKED_RECT locked_rect;
1198     HRESULT hr;
1199     UINT x;
1200     INT y, face;
1201
1202     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1203     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1204     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1205     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1206
1207     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1208             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1209     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1210
1211     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1212             D3DPOOL_DEFAULT, &texture, NULL);
1213     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1214
1215     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1216     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1217
1218     for (y = 0; y < 128; ++y)
1219     {
1220         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1221         for (x = 0; x < 64; ++x)
1222         {
1223             *ptr++ = 0xff0000ff;
1224         }
1225         for (x = 64; x < 128; ++x)
1226         {
1227             *ptr++ = 0xffff0000;
1228         }
1229     }
1230
1231     hr = IDirect3DSurface9_UnlockRect(surface);
1232     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1233
1234     hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1235     ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1236
1237     hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1238     ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1239
1240     IDirect3DSurface9_Release(face_surface);
1241
1242     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1243     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1244
1245     for (y = 0; y < 128; ++y)
1246     {
1247         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1248         for (x = 0; x < 64; ++x)
1249         {
1250             *ptr++ = 0xffff0000;
1251         }
1252         for (x = 64; x < 128; ++x)
1253         {
1254             *ptr++ = 0xff0000ff;
1255         }
1256     }
1257
1258     hr = IDirect3DSurface9_UnlockRect(surface);
1259     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1260
1261     /* Create cube faces */
1262     for (face = 1; face < 6; ++face)
1263     {
1264         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1265         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1266
1267         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1268         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1269
1270         IDirect3DSurface9_Release(face_surface);
1271     }
1272
1273     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1274     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1275
1276     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1277     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1278     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1279     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1280     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1281     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1282
1283     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1284     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1285
1286     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1287     {
1288         DWORD color;
1289
1290         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1291         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1292         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1293         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1294
1295         hr = IDirect3DDevice9_BeginScene(device);
1296         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1297
1298         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1299         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1300
1301         hr = IDirect3DDevice9_EndScene(device);
1302         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1303
1304         color = getPixelColor(device, 320, 240);
1305         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1306                 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1307                 color, address_modes[x].name);
1308
1309         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1310         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1311
1312         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1313         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1314     }
1315
1316     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1317     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1318
1319     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1320     IDirect3DCubeTexture9_Release(texture);
1321     IDirect3DSurface9_Release(surface);
1322 }
1323
1324 static void offscreen_test(IDirect3DDevice9 *device)
1325 {
1326     HRESULT hr;
1327     IDirect3DTexture9 *offscreenTexture = NULL;
1328     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1329     DWORD color;
1330
1331     static const float quad[][5] = {
1332         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1333         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1334         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1335         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1336     };
1337
1338     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1339     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1340
1341     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1342     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1343     if(!offscreenTexture) {
1344         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1345         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1346         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1347         if(!offscreenTexture) {
1348             skip("Cannot create an offscreen render target\n");
1349             goto out;
1350         }
1351     }
1352
1353     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1354     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1355     if(!backbuffer) {
1356         goto out;
1357     }
1358
1359     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1360     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1361     if(!offscreen) {
1362         goto out;
1363     }
1364
1365     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1366     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1367
1368     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1369     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1370     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1371     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1372     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1373     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1374     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1375     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1376     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1377     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1378
1379     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1380         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1381         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1382         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1383         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1384
1385         /* Draw without textures - Should result in a white quad */
1386         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1387         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1388
1389         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1390         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1391         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1392         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1393
1394         /* This time with the texture */
1395         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1396         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1397
1398         IDirect3DDevice9_EndScene(device);
1399     }
1400
1401     /* Center quad - should be white */
1402     color = getPixelColor(device, 320, 240);
1403     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1404     /* Some quad in the cleared part of the texture */
1405     color = getPixelColor(device, 170, 240);
1406     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1407     /* Part of the originally cleared back buffer */
1408     color = getPixelColor(device, 10, 10);
1409     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1410     if(0) {
1411         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1412          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1413          * the offscreen rendering mode this test would succeed or fail
1414          */
1415         color = getPixelColor(device, 10, 470);
1416         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1417     }
1418
1419     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1420
1421 out:
1422     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1423     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1424
1425     /* restore things */
1426     if(backbuffer) {
1427         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1428         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1429         IDirect3DSurface9_Release(backbuffer);
1430     }
1431     if(offscreenTexture) {
1432         IDirect3DTexture9_Release(offscreenTexture);
1433     }
1434     if(offscreen) {
1435         IDirect3DSurface9_Release(offscreen);
1436     }
1437 }
1438
1439 /* This test tests fog in combination with shaders.
1440  * What's tested: linear fog (vertex and table) with pixel shader
1441  *                linear table fog with non foggy vertex shader
1442  *                vertex fog with foggy vertex shader, non-linear
1443  *                fog with shader, non-linear fog with foggy shader,
1444  *                linear table fog with foggy shader
1445  */
1446 static void fog_with_shader_test(IDirect3DDevice9 *device)
1447 {
1448     HRESULT hr;
1449     DWORD color;
1450     union {
1451         float f;
1452         DWORD i;
1453     } start, end;
1454     unsigned int i, j;
1455
1456     /* basic vertex shader without fog computation ("non foggy") */
1457     static const DWORD vertex_shader_code1[] = {
1458         0xfffe0101,                                                             /* vs_1_1                       */
1459         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1460         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1461         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1462         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1463         0x0000ffff
1464     };
1465     /* basic vertex shader with reversed fog computation ("foggy") */
1466     static const DWORD vertex_shader_code2[] = {
1467         0xfffe0101,                                                             /* vs_1_1                        */
1468         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1469         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1470         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1471         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1472         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1473         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1474         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1475         0x0000ffff
1476     };
1477     /* basic pixel shader */
1478     static const DWORD pixel_shader_code[] = {
1479         0xffff0101,                                                             /* ps_1_1     */
1480         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1481         0x0000ffff
1482     };
1483
1484     static struct vertex quad[] = {
1485         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1486         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1487         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1488         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1489     };
1490
1491     static const D3DVERTEXELEMENT9 decl_elements[] = {
1492         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1493         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1494         D3DDECL_END()
1495     };
1496
1497     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1498     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1499     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1500
1501     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1502     static const struct test_data_t {
1503         int vshader;
1504         int pshader;
1505         D3DFOGMODE vfog;
1506         D3DFOGMODE tfog;
1507         unsigned int color[11];
1508     } test_data[] = {
1509         /* only pixel shader: */
1510         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1511         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1512         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1513         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1514         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1515         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1516         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1517         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1518         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1519         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1520         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1521         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1522         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1523         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1524         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1525
1526         /* vertex shader */
1527         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1528         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1529          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1530         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1531         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1532         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1533         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1534         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1535         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1536
1537         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1538         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1539         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1540         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1541         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1542         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1543
1544         /* vertex shader and pixel shader */
1545         /* The next 4 tests would read the fog coord output, but it isn't available.
1546          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1547          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1548          * These tests should be disabled if some other hardware behaves differently
1549          */
1550         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1551         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1552         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1553         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1554         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1555         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1556         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1557         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1558         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1559         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1560         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1561         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1562
1563         /* These use the Z coordinate with linear table fog */
1564         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1565         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1566         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1567         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1568         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1569         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1570         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1571         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1572         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1573         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1574         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1575         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1576
1577         /* Non-linear table fog without fog coord */
1578         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1579         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1580         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1581         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1582         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1583         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1584
1585 #if 0  /* FIXME: these fail on GeForce 8500 */
1586         /* foggy vertex shader */
1587         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1588         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1589          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1590         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1591         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1592          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1593         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1594         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1595          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1596         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1597         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1598          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1599 #endif
1600
1601         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1602          * all using the fixed fog-coord linear fog
1603          */
1604         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1605         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1606          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1607         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1608         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1609          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1610         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1611         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1612          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1613         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1614         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1615          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1616
1617         /* These use table fog. Here the shader-provided fog coordinate is
1618          * ignored and the z coordinate used instead
1619          */
1620         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1621         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1622         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1623         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1624         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1625         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1626         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1627         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1628         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1629     };
1630
1631     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1632     start.f=0.1f;
1633     end.f=0.9f;
1634
1635     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1636     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1637     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1638     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1639     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1640     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1641     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1642     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1643
1644     /* Setup initial states: No lighting, fog on, fog color */
1645     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1646     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1647     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1648     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1649     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1650     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1651     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1652     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1653
1654     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1655     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1656     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1657     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1658
1659     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1660     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1661     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1662     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1663     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1664
1665     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1666     {
1667         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1668         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1669         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1670         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1671         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1672         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1673         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1674         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1675
1676         for(j=0; j < 11; j++)
1677         {
1678             /* Don't use the whole zrange to prevent rounding errors */
1679             quad[0].z = 0.001f + (float)j / 10.02f;
1680             quad[1].z = 0.001f + (float)j / 10.02f;
1681             quad[2].z = 0.001f + (float)j / 10.02f;
1682             quad[3].z = 0.001f + (float)j / 10.02f;
1683
1684             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1685             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1686
1687             hr = IDirect3DDevice9_BeginScene(device);
1688             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1689
1690             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1691             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1692
1693             hr = IDirect3DDevice9_EndScene(device);
1694             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1695
1696             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1697             color = getPixelColor(device, 128, 240);
1698             ok(color_match(color, test_data[i].color[j], 13),
1699                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1700                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1701
1702             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1703         }
1704     }
1705
1706     /* reset states */
1707     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1708     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1709     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1710     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1711     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1712     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1713     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1714     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1715
1716     IDirect3DVertexShader9_Release(vertex_shader[1]);
1717     IDirect3DVertexShader9_Release(vertex_shader[2]);
1718     IDirect3DPixelShader9_Release(pixel_shader[1]);
1719     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1720 }
1721
1722 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1723     unsigned int i, x, y;
1724     HRESULT hr;
1725     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1726     D3DLOCKED_RECT locked_rect;
1727
1728     /* Generate the textures */
1729     for(i=0; i<2; i++)
1730     {
1731         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1732                                             D3DPOOL_MANAGED, &texture[i], NULL);
1733         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1734
1735         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1736         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1737         for (y = 0; y < 128; ++y)
1738         {
1739             if(i)
1740             { /* Set up black texture with 2x2 texel white spot in the middle */
1741                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1742                 for (x = 0; x < 128; ++x)
1743                 {
1744                     if(y>62 && y<66 && x>62 && x<66)
1745                         *ptr++ = 0xffffffff;
1746                     else
1747                         *ptr++ = 0xff000000;
1748                 }
1749             }
1750             else
1751             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1752                * (if multiplied with bumpenvmat)
1753               */
1754                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1755                 for (x = 0; x < 128; ++x)
1756                 {
1757                     if(abs(x-64)>abs(y-64))
1758                     {
1759                         if(x < 64)
1760                             *ptr++ = 0xc000;
1761                         else
1762                             *ptr++ = 0x4000;
1763                     }
1764                     else
1765                     {
1766                         if(y < 64)
1767                             *ptr++ = 0x0040;
1768                         else
1769                             *ptr++ = 0x00c0;
1770                     }
1771                 }
1772             }
1773         }
1774         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1775         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1776
1777         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1778         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1779
1780         /* Disable texture filtering */
1781         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1782         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1783         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1784         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1785
1786         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1787         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1788         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1789         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1790     }
1791 }
1792
1793 /* test the behavior of the texbem instruction
1794  * with normal 2D and projective 2D textures
1795  */
1796 static void texbem_test(IDirect3DDevice9 *device)
1797 {
1798     HRESULT hr;
1799     DWORD color;
1800     int i;
1801
1802     static const DWORD pixel_shader_code[] = {
1803         0xffff0101,                         /* ps_1_1*/
1804         0x00000042, 0xb00f0000,             /* tex t0*/
1805         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1806         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1807         0x0000ffff
1808     };
1809     static const DWORD double_texbem_code[] =  {
1810         0xffff0103,                                         /* ps_1_3           */
1811         0x00000042, 0xb00f0000,                             /* tex t0           */
1812         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1813         0x00000042, 0xb00f0002,                             /* tex t2           */
1814         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1815         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1816         0x0000ffff                                          /* end              */
1817     };
1818
1819
1820     static const float quad[][7] = {
1821         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1822         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1823         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1824         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1825     };
1826     static const float quad_proj[][9] = {
1827         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1828         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1829         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1830         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1831     };
1832
1833     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1834         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1835         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1836         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1837         D3DDECL_END()
1838     },{
1839         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1840         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1841         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1842         D3DDECL_END()
1843     } };
1844
1845     /* use asymmetric matrix to test loading */
1846     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1847
1848     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1849     IDirect3DPixelShader9       *pixel_shader       = NULL;
1850     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1851     D3DLOCKED_RECT locked_rect;
1852
1853     generate_bumpmap_textures(device);
1854
1855     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1856     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1857     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1858     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1859     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1860
1861     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1862     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1863
1864     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1865     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1866
1867     for(i=0; i<2; i++)
1868     {
1869         if(i)
1870         {
1871             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1872             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1873         }
1874
1875         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1876         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1877         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1878         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1879
1880         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1881         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1882         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1883         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1884
1885         hr = IDirect3DDevice9_BeginScene(device);
1886         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1887
1888         if(!i)
1889             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1890         else
1891             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1892         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1893
1894         hr = IDirect3DDevice9_EndScene(device);
1895         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1896
1897         color = getPixelColor(device, 320-32, 240);
1898         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1899         color = getPixelColor(device, 320+32, 240);
1900         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1901         color = getPixelColor(device, 320, 240-32);
1902         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1903         color = getPixelColor(device, 320, 240+32);
1904         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1905
1906         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1907         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1908
1909         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1910         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1911         IDirect3DPixelShader9_Release(pixel_shader);
1912
1913         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1914         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1915         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1916     }
1917
1918     /* clean up */
1919     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1920     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1921
1922     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1923     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1924
1925     for(i=0; i<2; i++)
1926     {
1927         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1928         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1929         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1930         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1931         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1932         IDirect3DTexture9_Release(texture);
1933     }
1934
1935     /* Test double texbem */
1936     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1937     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1938     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1939     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1940     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1941     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1942     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1943     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1944
1945     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1946     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1947     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1948     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1949
1950     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1951     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1952
1953     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1954     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1955     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1956     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1957     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1958     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1959
1960     {
1961         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1962 #define tex  0x00ff0000
1963 #define tex1 0x0000ff00
1964 #define origin 0x000000ff
1965         static const DWORD pixel_data[] = {
1966             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1967             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1968             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1969             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1970             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1971             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1972             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1973             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1974         };
1975 #undef tex1
1976 #undef tex2
1977 #undef origin
1978
1979         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1980         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1981         for(i = 0; i < 8; i++) {
1982             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1983         }
1984         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1985         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1986     }
1987
1988     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1989     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1990     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1991     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1992     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1993     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1994     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1995     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1996     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1997     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1998     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1999     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2000
2001     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
2002     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
2003     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2004     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2005     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2006     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2007     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2008     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2009     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2010     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2011
2012     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2013     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2014     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2015     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2016     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2017     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2018     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2019     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2020     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2021     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2022
2023     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2024     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2025     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2026     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2027     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2028     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2029     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2030     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2031     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2032     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2033     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2034     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2035     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2036     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2037     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2038     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2039
2040     hr = IDirect3DDevice9_BeginScene(device);
2041     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2042     if(SUCCEEDED(hr)) {
2043         static const float double_quad[] = {
2044             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2045              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2046             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2047              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2048         };
2049
2050         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2051         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2052         hr = IDirect3DDevice9_EndScene(device);
2053         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2054     }
2055     color = getPixelColor(device, 320, 240);
2056     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2057
2058     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2059     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2060     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2061     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2062     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2063     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2064     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2065     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2066     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2067     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2068
2069     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2070     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2071
2072     IDirect3DPixelShader9_Release(pixel_shader);
2073     IDirect3DTexture9_Release(texture);
2074     IDirect3DTexture9_Release(texture1);
2075     IDirect3DTexture9_Release(texture2);
2076 }
2077
2078 static void z_range_test(IDirect3DDevice9 *device)
2079 {
2080     const struct vertex quad[] =
2081     {
2082         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2083         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2084         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2085         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2086     };
2087     const struct vertex quad2[] =
2088     {
2089         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2090         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2091         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2092         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2093     };
2094
2095     const struct tvertex quad3[] =
2096     {
2097         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2098         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2099         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2100         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2101     };
2102     const struct tvertex quad4[] =
2103     {
2104         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2105         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2106         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2107         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2108     };
2109     HRESULT hr;
2110     DWORD color;
2111     IDirect3DVertexShader9 *shader;
2112     IDirect3DVertexDeclaration9 *decl;
2113     D3DCAPS9 caps;
2114     const DWORD shader_code[] = {
2115         0xfffe0101,                                     /* vs_1_1           */
2116         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2117         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2118         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2119         0x0000ffff                                      /* end              */
2120     };
2121     static const D3DVERTEXELEMENT9 decl_elements[] = {
2122         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2123         D3DDECL_END()
2124     };
2125
2126     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2127
2128     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2129      * then call Present. Then clear the color buffer to make sure it has some defined content
2130      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2131      * by the depth value.
2132      */
2133     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2134     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2135     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2136     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2137     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2138     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2139
2140     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2141     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2142     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2143     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2144     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2145     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2146     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2147     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2148     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2149     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2150
2151     hr = IDirect3DDevice9_BeginScene(device);
2152     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2153     if(hr == D3D_OK)
2154     {
2155         /* Test the untransformed vertex path */
2156         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2157         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2158         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2159         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2160         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2161         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2162
2163         /* Test the transformed vertex path */
2164         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2165         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2166
2167         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2168         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2169         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2170         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2171         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2172         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2173
2174         hr = IDirect3DDevice9_EndScene(device);
2175         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2176     }
2177
2178     /* Do not test the exact corner pixels, but go pretty close to them */
2179
2180     /* Clipped because z > 1.0 */
2181     color = getPixelColor(device, 28, 238);
2182     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2183     color = getPixelColor(device, 28, 241);
2184     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2185     {
2186         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2187     }
2188     else
2189     {
2190         ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2191     }
2192
2193     /* Not clipped, > z buffer clear value(0.75) */
2194     color = getPixelColor(device, 31, 238);
2195     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2196     color = getPixelColor(device, 31, 241);
2197     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2198     color = getPixelColor(device, 100, 238);
2199     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2200     color = getPixelColor(device, 100, 241);
2201     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2202
2203     /* Not clipped, < z buffer clear value */
2204     color = getPixelColor(device, 104, 238);
2205     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2206     color = getPixelColor(device, 104, 241);
2207     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2208     color = getPixelColor(device, 318, 238);
2209     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2210     color = getPixelColor(device, 318, 241);
2211     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2212
2213     /* Clipped because z < 0.0 */
2214     color = getPixelColor(device, 321, 238);
2215     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2216     color = getPixelColor(device, 321, 241);
2217     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2218     {
2219         ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2220     }
2221     else
2222     {
2223         ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2224     }
2225
2226     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2227     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2228
2229     /* Test the shader path */
2230     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2231         skip("Vertex shaders not supported\n");
2232         goto out;
2233     }
2234     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2235     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2236     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2237     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2238
2239     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2240
2241     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2242     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2243     IDirect3DDevice9_SetVertexShader(device, shader);
2244     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2245
2246     hr = IDirect3DDevice9_BeginScene(device);
2247     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2248     if(hr == D3D_OK)
2249     {
2250         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2251         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2252         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2253         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2254         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2255         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2256         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2257         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2258         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2259         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2260
2261         hr = IDirect3DDevice9_EndScene(device);
2262         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2263     }
2264
2265     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2266     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2267     IDirect3DDevice9_SetVertexShader(device, NULL);
2268     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2269
2270     IDirect3DVertexDeclaration9_Release(decl);
2271     IDirect3DVertexShader9_Release(shader);
2272
2273     /* Z < 1.0 */
2274     color = getPixelColor(device, 28, 238);
2275     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2276
2277     /* 1.0 < z < 0.75 */
2278     color = getPixelColor(device, 31, 238);
2279     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2280     color = getPixelColor(device, 100, 238);
2281     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2282
2283     /* 0.75 < z < 0.0 */
2284     color = getPixelColor(device, 104, 238);
2285     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2286     color = getPixelColor(device, 318, 238);
2287     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2288
2289     /* 0.0 < z */
2290     color = getPixelColor(device, 321, 238);
2291     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2292
2293     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2294     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2295
2296     out:
2297     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2298     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2299     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2300     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2301     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2302     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2303 }
2304
2305 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2306 {
2307     D3DSURFACE_DESC desc;
2308     D3DLOCKED_RECT l;
2309     HRESULT hr;
2310     unsigned int x, y;
2311     DWORD *mem;
2312
2313     memset(&desc, 0, sizeof(desc));
2314     memset(&l, 0, sizeof(l));
2315     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2316     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2317     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2318     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2319     if(FAILED(hr)) return;
2320
2321     for(y = 0; y < desc.Height; y++)
2322     {
2323         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2324         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2325         {
2326             mem[x] = color;
2327         }
2328     }
2329     hr = IDirect3DSurface9_UnlockRect(surface);
2330     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2331 }
2332
2333 /* This tests a variety of possible StretchRect() situations */
2334 static void stretchrect_test(IDirect3DDevice9 *device)
2335 {
2336     HRESULT hr;
2337     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2338     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2339     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2340     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2341     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2342     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2343     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2344     IDirect3DSurface9 *orig_rt = NULL;
2345     IDirect3DSurface9 *backbuffer = NULL;
2346     DWORD color;
2347
2348     RECT src_rect64 = {0, 0, 64, 64};
2349     RECT src_rect64_flipy = {0, 64, 64, 0};
2350     RECT dst_rect64 = {0, 0, 64, 64};
2351     RECT dst_rect64_flipy = {0, 64, 64, 0};
2352
2353     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2354     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2355     if(!orig_rt) {
2356         goto out;
2357     }
2358
2359     /* Create our temporary surfaces in system memory */
2360     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2361     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2362     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2363     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2364
2365     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2366     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2367     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2368     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2369     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2370     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2371     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2372
2373     /* Create render target surfaces */
2374     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2375     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2376     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2377     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2378     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2379     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2380     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2381     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2382
2383     /* Create render target textures */
2384     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2385     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2386     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2387     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2388     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2389     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2390     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2391     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2392     if (tex_rt32) {
2393         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2394         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2395     }
2396     if (tex_rt64) {
2397         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2398         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2399     }
2400     if (tex_rt_dest64) {
2401         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2402         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2403     }
2404     if (tex_rt_dest64) {
2405         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2406         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2407     }
2408
2409     /* Create regular textures in D3DPOOL_DEFAULT */
2410     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2411     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2412     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2413     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2414     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2415     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2416     if (tex32) {
2417         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2418         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2419     }
2420     if (tex64) {
2421         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2422         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2423     }
2424     if (tex_dest64) {
2425         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2426         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2427     }
2428
2429     /*********************************************************************
2430      * Tests for when the source parameter is an offscreen plain surface *
2431      *********************************************************************/
2432
2433     /* Fill the offscreen 64x64 surface with green */
2434     if (surf_offscreen64)
2435         fill_surface(surf_offscreen64, 0xff00ff00);
2436
2437     /* offscreenplain ==> offscreenplain, same size */
2438     if(surf_offscreen64 && surf_offscreen_dest64) {
2439         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2440         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2441
2442         if (hr == D3D_OK) {
2443             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2444             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2445         }
2446
2447         /* Blit without scaling */
2448         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2449         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2450
2451         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2452         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2453         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2454
2455         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2456         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2457         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2458     }
2459
2460     /* offscreenplain ==> rendertarget texture, same size */
2461     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2462         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2463         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2464
2465         /* We can't lock rendertarget textures, so copy to our temp surface first */
2466         if (hr == D3D_OK) {
2467             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2468             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2469         }
2470
2471         if (hr == D3D_OK) {
2472             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2473             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2474         }
2475
2476         /* Blit without scaling */
2477         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2478         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2479
2480         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2481         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2482         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2483
2484         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2485         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2486         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2487     }
2488
2489     /* offscreenplain ==> rendertarget surface, same size */
2490     if(surf_offscreen64 && surf_rt_dest64) {
2491         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2492         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2493
2494         if (hr == D3D_OK) {
2495             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2496             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2497         }
2498
2499         /* Blit without scaling */
2500         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2501         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2502
2503         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2504         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2505         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2506
2507         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2508         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2509         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2510     }
2511
2512     /* offscreenplain ==> texture, same size (should fail) */
2513     if(surf_offscreen64 && surf_tex_dest64) {
2514         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2515         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2516     }
2517
2518     /* Fill the smaller offscreen surface with red */
2519     fill_surface(surf_offscreen32, 0xffff0000);
2520
2521     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2522     if(surf_offscreen32 && surf_offscreen64) {
2523         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2524         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2525     }
2526
2527     /* offscreenplain ==> rendertarget texture, scaling */
2528     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2529         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2530         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2531
2532         /* We can't lock rendertarget textures, so copy to our temp surface first */
2533         if (hr == D3D_OK) {
2534             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2535             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2536         }
2537
2538         if (hr == D3D_OK) {
2539             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2540             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2541         }
2542     }
2543
2544     /* offscreenplain ==> rendertarget surface, scaling */
2545     if(surf_offscreen32 && surf_rt_dest64) {
2546         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2547         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2548
2549         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2550         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2551     }
2552
2553     /* offscreenplain ==> texture, scaling (should fail) */
2554     if(surf_offscreen32 && surf_tex_dest64) {
2555         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2556         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2557     }
2558
2559     /************************************************************
2560      * Tests for when the source parameter is a regular texture *
2561      ************************************************************/
2562
2563     /* Fill the surface of the regular texture with blue */
2564     if (surf_tex64 && surf_temp64) {
2565         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2566         fill_surface(surf_temp64, 0xff0000ff);
2567         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2568         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2569     }
2570
2571     /* texture ==> offscreenplain, same size */
2572     if(surf_tex64 && surf_offscreen64) {
2573         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2574         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2575     }
2576
2577     /* texture ==> rendertarget texture, same size */
2578     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2579         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2580         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2581
2582         /* We can't lock rendertarget textures, so copy to our temp surface first */
2583         if (hr == D3D_OK) {
2584             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2585             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2586         }
2587
2588         if (hr == D3D_OK) {
2589             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2590             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2591         }
2592
2593         /* Blit without scaling */
2594         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2595         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2596
2597         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2598         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2599         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2600
2601         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2602         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2603         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2604     }
2605
2606     /* texture ==> rendertarget surface, same size */
2607     if(surf_tex64 && surf_rt_dest64) {
2608         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2609         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2610
2611         if (hr == D3D_OK) {
2612             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2613             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2614         }
2615
2616         /* Blit without scaling */
2617         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2618         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2619
2620         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2621         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2622         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2623
2624         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2625         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2626         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2627     }
2628
2629     /* texture ==> texture, same size (should fail) */
2630     if(surf_tex64 && surf_tex_dest64) {
2631         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2632         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2633     }
2634
2635     /* Fill the surface of the smaller regular texture with red */
2636     if (surf_tex32 && surf_temp32) {
2637         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2638         fill_surface(surf_temp32, 0xffff0000);
2639         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2640         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2641     }
2642
2643     /* texture ==> offscreenplain, scaling (should fail) */
2644     if(surf_tex32 && surf_offscreen64) {
2645         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2646         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2647     }
2648
2649     /* texture ==> rendertarget texture, scaling */
2650     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2651         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2652         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2653
2654         /* We can't lock rendertarget textures, so copy to our temp surface first */
2655         if (hr == D3D_OK) {
2656             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2657             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2658         }
2659
2660         if (hr == D3D_OK) {
2661             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2662             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2663         }
2664     }
2665
2666     /* texture ==> rendertarget surface, scaling */
2667     if(surf_tex32 && surf_rt_dest64) {
2668         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2669         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2670
2671         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2672         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2673     }
2674
2675     /* texture ==> texture, scaling (should fail) */
2676     if(surf_tex32 && surf_tex_dest64) {
2677         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2678         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2679     }
2680
2681     /*****************************************************************
2682      * Tests for when the source parameter is a rendertarget texture *
2683      *****************************************************************/
2684
2685     /* Fill the surface of the rendertarget texture with white */
2686     if (surf_tex_rt64 && surf_temp64) {
2687         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2688         fill_surface(surf_temp64, 0xffffffff);
2689         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2690         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2691     }
2692
2693     /* rendertarget texture ==> offscreenplain, same size */
2694     if(surf_tex_rt64 && surf_offscreen64) {
2695         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2696         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2697     }
2698
2699     /* rendertarget texture ==> rendertarget texture, same size */
2700     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2701         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2702         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2703
2704         /* We can't lock rendertarget textures, so copy to our temp surface first */
2705         if (hr == D3D_OK) {
2706             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2707             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2708         }
2709
2710         if (hr == D3D_OK) {
2711             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2712             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2713         }
2714
2715         /* Blit without scaling */
2716         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2717         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2718
2719         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2720         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2721         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2722
2723         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2724         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2725         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2726     }
2727
2728     /* rendertarget texture ==> rendertarget surface, same size */
2729     if(surf_tex_rt64 && surf_rt_dest64) {
2730         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2731         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2732
2733         if (hr == D3D_OK) {
2734             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2735             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2736         }
2737
2738         /* Blit without scaling */
2739         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2740         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2741
2742         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2743         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2744         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2745
2746         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2747         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2748         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2749     }
2750
2751     /* rendertarget texture ==> texture, same size (should fail) */
2752     if(surf_tex_rt64 && surf_tex_dest64) {
2753         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2754         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2755     }
2756
2757     /* Fill the surface of the smaller rendertarget texture with red */
2758     if (surf_tex_rt32 && surf_temp32) {
2759         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2760         fill_surface(surf_temp32, 0xffff0000);
2761         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2762         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2763     }
2764
2765     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2766     if(surf_tex_rt32 && surf_offscreen64) {
2767         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2768         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2769     }
2770
2771     /* rendertarget texture ==> rendertarget texture, scaling */
2772     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2773         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2774         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2775
2776         /* We can't lock rendertarget textures, so copy to our temp surface first */
2777         if (hr == D3D_OK) {
2778             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2779             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2780         }
2781
2782         if (hr == D3D_OK) {
2783             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2784             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2785         }
2786     }
2787
2788     /* rendertarget texture ==> rendertarget surface, scaling */
2789     if(surf_tex_rt32 && surf_rt_dest64) {
2790         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2791         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2792
2793         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2794         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2795     }
2796
2797     /* rendertarget texture ==> texture, scaling (should fail) */
2798     if(surf_tex_rt32 && surf_tex_dest64) {
2799         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2800         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2801     }
2802
2803     /*****************************************************************
2804      * Tests for when the source parameter is a rendertarget surface *
2805      *****************************************************************/
2806
2807     /* Fill the surface of the rendertarget surface with black */
2808     if (surf_rt64)
2809         fill_surface(surf_rt64, 0xff000000);
2810
2811     /* rendertarget texture ==> offscreenplain, same size */
2812     if(surf_rt64 && surf_offscreen64) {
2813         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2814         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2815     }
2816
2817     /* rendertarget surface ==> rendertarget texture, same size */
2818     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2819         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2820         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2821
2822         /* We can't lock rendertarget textures, so copy to our temp surface first */
2823         if (hr == D3D_OK) {
2824             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2825             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2826         }
2827
2828         if (hr == D3D_OK) {
2829             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2830             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2831         }
2832
2833         /* Blit without scaling */
2834         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2835         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2836
2837         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2838         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2839         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2840
2841         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2842         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2843         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2844     }
2845
2846     /* rendertarget surface ==> rendertarget surface, same size */
2847     if(surf_rt64 && surf_rt_dest64) {
2848         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2849         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2850
2851         if (hr == D3D_OK) {
2852             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2853             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2854         }
2855
2856         /* Blit without scaling */
2857         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2858         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2859
2860         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2861         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
2862         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2863
2864         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2865         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2866         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2867     }
2868
2869     /* rendertarget surface ==> texture, same size (should fail) */
2870     if(surf_rt64 && surf_tex_dest64) {
2871         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2872         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2873     }
2874
2875     /* Fill the surface of the smaller rendertarget texture with red */
2876     if (surf_rt32)
2877         fill_surface(surf_rt32, 0xffff0000);
2878
2879     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2880     if(surf_rt32 && surf_offscreen64) {
2881         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2882         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2883     }
2884
2885     /* rendertarget surface ==> rendertarget texture, scaling */
2886     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2887         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2888         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2889
2890         /* We can't lock rendertarget textures, so copy to our temp surface first */
2891         if (hr == D3D_OK) {
2892             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2893             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2894         }
2895
2896         if (hr == D3D_OK) {
2897             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2898             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2899         }
2900     }
2901
2902     /* rendertarget surface ==> rendertarget surface, scaling */
2903     if(surf_rt32 && surf_rt_dest64) {
2904         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2905         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2906
2907         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2908         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2909     }
2910
2911     /* rendertarget surface ==> texture, scaling (should fail) */
2912     if(surf_rt32 && surf_tex_dest64) {
2913         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2914         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2915     }
2916
2917     /* backbuffer ==> surface tests (no scaling) */
2918     if(backbuffer && surf_tex_rt_dest640_480)
2919     {
2920         RECT src_rect = {0, 0, 640, 480};
2921         RECT src_rect_flipy = {0, 480, 640, 0};
2922         RECT dst_rect = {0, 0, 640, 480};
2923         RECT dst_rect_flipy = {0, 480, 640, 0};
2924
2925         /* Blit with NULL rectangles */
2926         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
2927         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
2928
2929         /* Blit without scaling */
2930         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
2931         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2932
2933         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2934         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
2935         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2936
2937         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2938         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
2939         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2940     }
2941
2942     /* TODO: Test format conversions */
2943
2944
2945 out:
2946     /* Clean up */
2947     if (backbuffer)
2948         IDirect3DSurface9_Release(backbuffer);
2949     if (surf_rt32)
2950         IDirect3DSurface9_Release(surf_rt32);
2951     if (surf_rt64)
2952         IDirect3DSurface9_Release(surf_rt64);
2953     if (surf_rt_dest64)
2954         IDirect3DSurface9_Release(surf_rt_dest64);
2955     if (surf_temp32)
2956         IDirect3DSurface9_Release(surf_temp32);
2957     if (surf_temp64)
2958         IDirect3DSurface9_Release(surf_temp64);
2959     if (surf_offscreen32)
2960         IDirect3DSurface9_Release(surf_offscreen32);
2961     if (surf_offscreen64)
2962         IDirect3DSurface9_Release(surf_offscreen64);
2963     if (surf_offscreen_dest64)
2964         IDirect3DSurface9_Release(surf_offscreen_dest64);
2965
2966     if (tex_rt32) {
2967         if (surf_tex_rt32)
2968             IDirect3DSurface9_Release(surf_tex_rt32);
2969         IDirect3DTexture9_Release(tex_rt32);
2970     }
2971     if (tex_rt64) {
2972         if (surf_tex_rt64)
2973             IDirect3DSurface9_Release(surf_tex_rt64);
2974         IDirect3DTexture9_Release(tex_rt64);
2975     }
2976     if (tex_rt_dest64) {
2977         if (surf_tex_rt_dest64)
2978             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2979         IDirect3DTexture9_Release(tex_rt_dest64);
2980     }
2981     if (tex_rt_dest640_480) {
2982         if (surf_tex_rt_dest640_480)
2983             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
2984         IDirect3DTexture9_Release(tex_rt_dest640_480);
2985     }
2986     if (tex32) {
2987         if (surf_tex32)
2988             IDirect3DSurface9_Release(surf_tex32);
2989         IDirect3DTexture9_Release(tex32);
2990     }
2991     if (tex64) {
2992         if (surf_tex64)
2993             IDirect3DSurface9_Release(surf_tex64);
2994         IDirect3DTexture9_Release(tex64);
2995     }
2996     if (tex_dest64) {
2997         if (surf_tex_dest64)
2998             IDirect3DSurface9_Release(surf_tex_dest64);
2999         IDirect3DTexture9_Release(tex_dest64);
3000     }
3001
3002     if (orig_rt) {
3003         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3004         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3005         IDirect3DSurface9_Release(orig_rt);
3006     }
3007 }
3008
3009 static void maxmip_test(IDirect3DDevice9 *device)
3010 {
3011     IDirect3DTexture9 *texture = NULL;
3012     IDirect3DSurface9 *surface = NULL;
3013     HRESULT hr;
3014     DWORD color;
3015     static const struct
3016     {
3017         struct
3018         {
3019             float x, y, z;
3020             float s, t;
3021         }
3022         v[4];
3023     }
3024     quads[] =
3025     {
3026         {{
3027             {-1.0, -1.0,  0.0,  0.0,  0.0},
3028             {-1.0,  0.0,  0.0,  0.0,  1.0},
3029             { 0.0, -1.0,  0.0,  1.0,  0.0},
3030             { 0.0,  0.0,  0.0,  1.0,  1.0},
3031         }},
3032         {{
3033             { 0.0, -1.0,  0.0,  0.0,  0.0},
3034             { 0.0,  0.0,  0.0,  0.0,  1.0},
3035             { 1.0, -1.0,  0.0,  1.0,  0.0},
3036             { 1.0,  0.0,  0.0,  1.0,  1.0},
3037         }},
3038         {{
3039             { 0.0,  0.0,  0.0,  0.0,  0.0},
3040             { 0.0,  1.0,  0.0,  0.0,  1.0},
3041             { 1.0,  0.0,  0.0,  1.0,  0.0},
3042             { 1.0,  1.0,  0.0,  1.0,  1.0},
3043         }},
3044         {{
3045             {-1.0,  0.0,  0.0,  0.0,  0.0},
3046             {-1.0,  1.0,  0.0,  0.0,  1.0},
3047             { 0.0,  0.0,  0.0,  1.0,  0.0},
3048             { 0.0,  1.0,  0.0,  1.0,  1.0},
3049         }},
3050     };
3051
3052     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3053                                         &texture, NULL);
3054     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3055     if(!texture)
3056     {
3057         skip("Failed to create test texture\n");
3058         return;
3059     }
3060
3061     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3062     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3063     fill_surface(surface, 0xffff0000);
3064     IDirect3DSurface9_Release(surface);
3065     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3066     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3067     fill_surface(surface, 0xff00ff00);
3068     IDirect3DSurface9_Release(surface);
3069     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3070     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3071     fill_surface(surface, 0xff0000ff);
3072     IDirect3DSurface9_Release(surface);
3073
3074     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3075     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3076     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3077     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3078
3079     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3080     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3081
3082     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3083     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3084
3085     hr = IDirect3DDevice9_BeginScene(device);
3086     if(SUCCEEDED(hr))
3087     {
3088         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3089         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3090         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3091         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3092
3093         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3094         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3095         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3096         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3097
3098         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3099         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3100         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3101         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3102
3103         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3104         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3105         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3106         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3107         hr = IDirect3DDevice9_EndScene(device);
3108         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3109     }
3110
3111     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3112     color = getPixelColor(device, 160, 360);
3113     ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3114     color = getPixelColor(device, 480, 360);
3115     ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3116     color = getPixelColor(device, 480, 120);
3117     ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3118     color = getPixelColor(device, 160, 120);
3119     ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3120     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3121     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3122
3123     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3124     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3125
3126     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3127     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3128
3129     hr = IDirect3DDevice9_BeginScene(device);
3130     if(SUCCEEDED(hr))
3131     {
3132         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3133         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3134         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3135         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3136
3137         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3138         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3139         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3140         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3141
3142         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3143         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3144         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3145         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3146
3147         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3148         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3149         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3150         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3151         hr = IDirect3DDevice9_EndScene(device);
3152         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3153     }
3154
3155     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3156      * level 3 (> levels in texture) samples from the highest level in the
3157      * texture (level 2). */
3158     color = getPixelColor(device, 160, 360);
3159     ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3160     color = getPixelColor(device, 480, 360);
3161     ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3162     color = getPixelColor(device, 480, 120);
3163     ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3164     color = getPixelColor(device, 160, 120);
3165     ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3166     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3167     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3168
3169     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3170     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3171
3172     hr = IDirect3DDevice9_BeginScene(device);
3173     if(SUCCEEDED(hr))
3174     {
3175         DWORD ret;
3176
3177         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3178         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3179         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3180         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3181         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3182         ret = IDirect3DTexture9_SetLOD(texture, 1);
3183         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3184         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3185         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3186
3187         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3188         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3189         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3190         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3191         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3192         ret = IDirect3DTexture9_SetLOD(texture, 2);
3193         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3194         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3195         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3196
3197         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3198         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3199         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3200         ret = IDirect3DTexture9_SetLOD(texture, 1);
3201         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3202         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3203         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3204
3205         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3206         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3207         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3208         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3209         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3210         ret = IDirect3DTexture9_SetLOD(texture, 1);
3211         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3212         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3213         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3214         hr = IDirect3DDevice9_EndScene(device);
3215         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3216     }
3217
3218     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3219      * level 3 (> levels in texture) samples from the highest level in the
3220      * texture (level 2). */
3221     color = getPixelColor(device, 160, 360);
3222     ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3223     color = getPixelColor(device, 480, 360);
3224     ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3225     color = getPixelColor(device, 480, 120);
3226     ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3227     color = getPixelColor(device, 160, 120);
3228     ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3229
3230     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3231     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3232
3233     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3234     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3235     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3236     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3237     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3238     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3239     IDirect3DTexture9_Release(texture);
3240 }
3241
3242 static void release_buffer_test(IDirect3DDevice9 *device)
3243 {
3244     IDirect3DVertexBuffer9 *vb = NULL;
3245     IDirect3DIndexBuffer9 *ib = NULL;
3246     HRESULT hr;
3247     BYTE *data;
3248     LONG ref;
3249
3250     static const struct vertex quad[] = {
3251         {-1.0,      -1.0,       0.1,        0xffff0000},
3252         {-1.0,       1.0,       0.1,        0xffff0000},
3253         { 1.0,       1.0,       0.1,        0xffff0000},
3254
3255         {-1.0,      -1.0,       0.1,        0xff00ff00},
3256         {-1.0,       1.0,       0.1,        0xff00ff00},
3257         { 1.0,       1.0,       0.1,        0xff00ff00}
3258     };
3259     short indices[] = {3, 4, 5};
3260
3261     /* Index and vertex buffers should always be creatable */
3262     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3263                                               D3DPOOL_MANAGED, &vb, NULL);
3264     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3265     if(!vb) {
3266         skip("Failed to create a vertex buffer\n");
3267         return;
3268     }
3269     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3270     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3271     if(!ib) {
3272         skip("Failed to create an index buffer\n");
3273         return;
3274     }
3275
3276     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3277     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3278     memcpy(data, quad, sizeof(quad));
3279     hr = IDirect3DVertexBuffer9_Unlock(vb);
3280     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3281
3282     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3283     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3284     memcpy(data, indices, sizeof(indices));
3285     hr = IDirect3DIndexBuffer9_Unlock(ib);
3286     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3287
3288     hr = IDirect3DDevice9_SetIndices(device, ib);
3289     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3290     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3291     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3292     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3293     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3294
3295     /* Now destroy the bound index buffer and draw again */
3296     ref = IDirect3DIndexBuffer9_Release(ib);
3297     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3298
3299     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3300     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3301
3302     hr = IDirect3DDevice9_BeginScene(device);
3303     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3304     if(SUCCEEDED(hr))
3305     {
3306         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3307          * making assumptions about the indices or vertices
3308          */
3309         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3310         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3311         hr = IDirect3DDevice9_EndScene(device);
3312         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3313     }
3314
3315     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3316     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3317
3318     hr = IDirect3DDevice9_SetIndices(device, NULL);
3319     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3320     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3321     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3322
3323     /* Index buffer was already destroyed as part of the test */
3324     IDirect3DVertexBuffer9_Release(vb);
3325 }
3326
3327 static void float_texture_test(IDirect3DDevice9 *device)
3328 {
3329     IDirect3D9 *d3d = NULL;
3330     HRESULT hr;
3331     IDirect3DTexture9 *texture = NULL;
3332     D3DLOCKED_RECT lr;
3333     float *data;
3334     DWORD color;
3335     float quad[] = {
3336         -1.0,      -1.0,       0.1,     0.0,    0.0,
3337         -1.0,       1.0,       0.1,     0.0,    1.0,
3338          1.0,      -1.0,       0.1,     1.0,    0.0,
3339          1.0,       1.0,       0.1,     1.0,    1.0,
3340     };
3341
3342     memset(&lr, 0, sizeof(lr));
3343     IDirect3DDevice9_GetDirect3D(device, &d3d);
3344     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3345                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3346         skip("D3DFMT_R32F textures not supported\n");
3347         goto out;
3348     }
3349
3350     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3351                                         D3DPOOL_MANAGED, &texture, NULL);
3352     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3353     if(!texture) {
3354         skip("Failed to create R32F texture\n");
3355         goto out;
3356     }
3357
3358     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3359     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3360     data = lr.pBits;
3361     *data = 0.0;
3362     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3363     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3364
3365     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3366     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3367
3368     hr = IDirect3DDevice9_BeginScene(device);
3369     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3370     if(SUCCEEDED(hr))
3371     {
3372         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3373         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3374
3375         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3376         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3377
3378         hr = IDirect3DDevice9_EndScene(device);
3379         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3380     }
3381     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3382     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3383
3384     color = getPixelColor(device, 240, 320);
3385     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3386
3387     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3388     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3389
3390 out:
3391     if(texture) IDirect3DTexture9_Release(texture);
3392     IDirect3D9_Release(d3d);
3393 }
3394
3395 static void g16r16_texture_test(IDirect3DDevice9 *device)
3396 {
3397     IDirect3D9 *d3d = NULL;
3398     HRESULT hr;
3399     IDirect3DTexture9 *texture = NULL;
3400     D3DLOCKED_RECT lr;
3401     DWORD *data;
3402     DWORD color;
3403     float quad[] = {
3404        -1.0,      -1.0,       0.1,     0.0,    0.0,
3405        -1.0,       1.0,       0.1,     0.0,    1.0,
3406         1.0,      -1.0,       0.1,     1.0,    0.0,
3407         1.0,       1.0,       0.1,     1.0,    1.0,
3408     };
3409
3410     memset(&lr, 0, sizeof(lr));
3411     IDirect3DDevice9_GetDirect3D(device, &d3d);
3412     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3413        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3414            skip("D3DFMT_G16R16 textures not supported\n");
3415            goto out;
3416     }
3417
3418     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3419                                         D3DPOOL_MANAGED, &texture, NULL);
3420     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3421     if(!texture) {
3422         skip("Failed to create D3DFMT_G16R16 texture\n");
3423         goto out;
3424     }
3425
3426     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3427     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3428     data = lr.pBits;
3429     *data = 0x0f00f000;
3430     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3431     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3432
3433     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3434     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3435
3436     hr = IDirect3DDevice9_BeginScene(device);
3437     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3438     if(SUCCEEDED(hr))
3439     {
3440         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3441         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3442
3443         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3444         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3445
3446         hr = IDirect3DDevice9_EndScene(device);
3447         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3448     }
3449     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3450     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3451
3452     color = getPixelColor(device, 240, 320);
3453     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3454        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3455
3456     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3457     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3458
3459 out:
3460     if(texture) IDirect3DTexture9_Release(texture);
3461     IDirect3D9_Release(d3d);
3462 }
3463
3464 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3465 {
3466     HRESULT hr;
3467     IDirect3D9 *d3d;
3468     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3469     D3DCAPS9 caps;
3470     IDirect3DTexture9 *texture = NULL;
3471     IDirect3DVolumeTexture9 *volume = NULL;
3472     unsigned int x, y, z;
3473     D3DLOCKED_RECT lr;
3474     D3DLOCKED_BOX lb;
3475     DWORD color;
3476     UINT w, h;
3477     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3478     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3479                            0.0, 1.0, 0.0, 0.0,
3480                            0.0, 0.0, 1.0, 0.0,
3481                            0.0, 0.0, 0.0, 1.0};
3482     static const D3DVERTEXELEMENT9 decl_elements[] = {
3483         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3484         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3485         D3DDECL_END()
3486     };
3487     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3488         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3489         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3490         D3DDECL_END()
3491     };
3492     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3493         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3494         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3495         D3DDECL_END()
3496     };
3497     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3498                                                  0x00, 0xff, 0x00, 0x00,
3499                                                  0x00, 0x00, 0x00, 0x00,
3500                                                  0x00, 0x00, 0x00, 0x00};
3501
3502     memset(&lr, 0, sizeof(lr));
3503     memset(&lb, 0, sizeof(lb));
3504     IDirect3DDevice9_GetDirect3D(device, &d3d);
3505     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3506                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3507         fmt = D3DFMT_A16B16G16R16;
3508     }
3509     IDirect3D9_Release(d3d);
3510
3511     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3512     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3513     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3514     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3515     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3516     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3517     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3518     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3519     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3520     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3521     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3522     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3523     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3524     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3525     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3526     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3527     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3528     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3529     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3530     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3531     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3532     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3533     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3534     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3535
3536     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3537     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3538     w = min(1024, caps.MaxTextureWidth);
3539     h = min(1024, caps.MaxTextureHeight);
3540     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3541                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3542     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3543     if(!texture) {
3544         skip("Failed to create the test texture\n");
3545         return;
3546     }
3547
3548     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3549      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3550      * 1.0 in red and green for the x and y coords
3551      */
3552     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3553     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3554     for(y = 0; y < h; y++) {
3555         for(x = 0; x < w; x++) {
3556             double r_f = (double) y / (double) h;
3557             double g_f = (double) x / (double) w;
3558             if(fmt == D3DFMT_A16B16G16R16) {
3559                 unsigned short r, g;
3560                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3561                 r = (unsigned short) (r_f * 65536.0);
3562                 g = (unsigned short) (g_f * 65536.0);
3563                 dst[0] = r;
3564                 dst[1] = g;
3565                 dst[2] = 0;
3566                 dst[3] = 65535;
3567             } else {
3568                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3569                 unsigned char r = (unsigned char) (r_f * 255.0);
3570                 unsigned char g = (unsigned char) (g_f * 255.0);
3571                 dst[0] = 0;
3572                 dst[1] = g;
3573                 dst[2] = r;
3574                 dst[3] = 255;
3575             }
3576         }
3577     }
3578     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3579     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3580     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3581     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3582
3583     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3584     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3585     hr = IDirect3DDevice9_BeginScene(device);
3586     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3587     if(SUCCEEDED(hr))
3588     {
3589         float quad1[] = {
3590             -1.0,      -1.0,       0.1,     1.0,    1.0,
3591             -1.0,       0.0,       0.1,     1.0,    1.0,
3592              0.0,      -1.0,       0.1,     1.0,    1.0,
3593              0.0,       0.0,       0.1,     1.0,    1.0,
3594         };
3595         float quad2[] = {
3596             -1.0,       0.0,       0.1,     1.0,    1.0,
3597             -1.0,       1.0,       0.1,     1.0,    1.0,
3598              0.0,       0.0,       0.1,     1.0,    1.0,
3599              0.0,       1.0,       0.1,     1.0,    1.0,
3600         };
3601         float quad3[] = {
3602              0.0,       0.0,       0.1,     0.5,    0.5,
3603              0.0,       1.0,       0.1,     0.5,    0.5,
3604              1.0,       0.0,       0.1,     0.5,    0.5,
3605              1.0,       1.0,       0.1,     0.5,    0.5,
3606         };
3607         float quad4[] = {
3608              320,       480,       0.1,     1.0,    0.0,    1.0,
3609              320,       240,       0.1,     1.0,    0.0,    1.0,
3610              640,       480,       0.1,     1.0,    0.0,    1.0,
3611              640,       240,       0.1,     1.0,    0.0,    1.0,
3612         };
3613         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3614                           0.0, 0.0, 0.0, 0.0,
3615                           0.0, 0.0, 0.0, 0.0,
3616                           0.0, 0.0, 0.0, 0.0};
3617
3618         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3619         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3620         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3621         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3622         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3623
3624         /* What happens with transforms enabled? */
3625         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3626         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3627         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3628         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3629
3630         /* What happens if 4 coords are used, but only 2 given ?*/
3631         mat[8] = 1.0;
3632         mat[13] = 1.0;
3633         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3634         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3635         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3636         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3637         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3638         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3639
3640         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3641          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3642          * due to the coords in the vertices. (turns out red, indeed)
3643          */
3644         memset(mat, 0, sizeof(mat));
3645         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3646         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3647         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3648         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3649         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3650         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3651         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3652         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3653
3654         hr = IDirect3DDevice9_EndScene(device);
3655         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3656     }
3657     color = getPixelColor(device, 160, 360);
3658     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3659     color = getPixelColor(device, 160, 120);
3660     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3661     color = getPixelColor(device, 480, 120);
3662     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3663     color = getPixelColor(device, 480, 360);
3664     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3665     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3666     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3667
3668     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3669     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3670
3671     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3672     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3673     hr = IDirect3DDevice9_BeginScene(device);
3674     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3675     if(SUCCEEDED(hr))
3676     {
3677         float quad1[] = {
3678             -1.0,      -1.0,       0.1,     0.8,    0.2,
3679             -1.0,       0.0,       0.1,     0.8,    0.2,
3680              0.0,      -1.0,       0.1,     0.8,    0.2,
3681              0.0,       0.0,       0.1,     0.8,    0.2,
3682         };
3683         float quad2[] = {
3684             -1.0,       0.0,       0.1,     0.5,    1.0,
3685             -1.0,       1.0,       0.1,     0.5,    1.0,
3686              0.0,       0.0,       0.1,     0.5,    1.0,
3687              0.0,       1.0,       0.1,     0.5,    1.0,
3688         };
3689         float quad3[] = {
3690              0.0,       0.0,       0.1,     0.5,    1.0,
3691              0.0,       1.0,       0.1,     0.5,    1.0,
3692              1.0,       0.0,       0.1,     0.5,    1.0,
3693              1.0,       1.0,       0.1,     0.5,    1.0,
3694         };
3695         float quad4[] = {
3696              0.0,      -1.0,       0.1,     0.8,    0.2,
3697              0.0,       0.0,       0.1,     0.8,    0.2,
3698              1.0,      -1.0,       0.1,     0.8,    0.2,
3699              1.0,       0.0,       0.1,     0.8,    0.2,
3700         };
3701         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3702                           0.0, 0.0, 0.0, 0.0,
3703                           0.0, 1.0, 0.0, 0.0,
3704                           0.0, 0.0, 0.0, 0.0};
3705
3706         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3707          */
3708         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3709         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3710         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3711         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3712
3713         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3714         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3715
3716         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3717          * it behaves like COUNT2 because normal textures require 2 coords
3718          */
3719         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3720         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3721         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3722         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3723
3724         /* Just to be sure, the same as quad2 above */
3725         memset(mat, 0, sizeof(mat));
3726         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3727         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3728         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3729         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3730         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3731         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3732
3733         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3734          * used? And what happens to the first?
3735          */
3736         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3737         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3738         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3739         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3740
3741         hr = IDirect3DDevice9_EndScene(device);
3742         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3743     }
3744     color = getPixelColor(device, 160, 360);
3745     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3746     color = getPixelColor(device, 160, 120);
3747     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3748     color = getPixelColor(device, 480, 120);
3749     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3750        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3751     color = getPixelColor(device, 480, 360);
3752     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3753        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3754     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3755     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3756
3757     IDirect3DTexture9_Release(texture);
3758
3759     /* Test projected textures, without any fancy matrices */
3760     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3761     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3762     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3763     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3764     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3765     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3766     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3767     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3768
3769     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3770     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3771     for(x = 0; x < 4; x++) {
3772         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3773     }
3774     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3775     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3776     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3777     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3778
3779     hr = IDirect3DDevice9_BeginScene(device);
3780     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3781     if(SUCCEEDED(hr))
3782     {
3783         const float proj_quads[] = {
3784            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3785             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3786            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3787             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3788            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3789             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3790            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3791             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3792         };
3793
3794         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3795         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3796         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3797         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3798
3799         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3800         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3801         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3802         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3803
3804         hr = IDirect3DDevice9_EndScene(device);
3805         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3806     }
3807
3808     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3809     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3810     IDirect3DTexture9_Release(texture);
3811
3812     color = getPixelColor(device, 158, 118);
3813     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3814     color = getPixelColor(device, 162, 118);
3815     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3816     color = getPixelColor(device, 158, 122);
3817     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3818     color = getPixelColor(device, 162, 122);
3819     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3820
3821     color = getPixelColor(device, 158, 178);
3822     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3823     color = getPixelColor(device, 162, 178);
3824     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3825     color = getPixelColor(device, 158, 182);
3826     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3827     color = getPixelColor(device, 162, 182);
3828     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3829
3830     color = getPixelColor(device, 318, 118);
3831     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3832     color = getPixelColor(device, 322, 118);
3833     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3834     color = getPixelColor(device, 318, 122);
3835     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3836     color = getPixelColor(device, 322, 122);
3837     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3838
3839     color = getPixelColor(device, 318, 178);
3840     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3841     color = getPixelColor(device, 322, 178);
3842     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3843     color = getPixelColor(device, 318, 182);
3844     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3845     color = getPixelColor(device, 322, 182);
3846     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3847
3848     color = getPixelColor(device, 238, 298);
3849     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3850     color = getPixelColor(device, 242, 298);
3851     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3852     color = getPixelColor(device, 238, 302);
3853     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3854     color = getPixelColor(device, 242, 302);
3855     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3856
3857     color = getPixelColor(device, 238, 388);
3858     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3859     color = getPixelColor(device, 242, 388);
3860     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3861     color = getPixelColor(device, 238, 392);
3862     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3863     color = getPixelColor(device, 242, 392);
3864     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3865
3866     color = getPixelColor(device, 478, 298);
3867     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3868     color = getPixelColor(device, 482, 298);
3869     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3870     color = getPixelColor(device, 478, 302);
3871     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3872     color = getPixelColor(device, 482, 302);
3873     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3874
3875     color = getPixelColor(device, 478, 388);
3876     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3877     color = getPixelColor(device, 482, 388);
3878     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3879     color = getPixelColor(device, 478, 392);
3880     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3881     color = getPixelColor(device, 482, 392);
3882     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3883
3884     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3885     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3886
3887     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3888     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3889     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3890      * Thus watch out if sampling from texels between 0 and 1.
3891      */
3892     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3893     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3894        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3895     if(!volume) {
3896         skip("Failed to create a volume texture\n");
3897         goto out;
3898     }
3899
3900     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3901     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3902     for(z = 0; z < 32; z++) {
3903         for(y = 0; y < 32; y++) {
3904             for(x = 0; x < 32; x++) {
3905                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3906                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3907                 float r_f = (float) x / 31.0;
3908                 float g_f = (float) y / 31.0;
3909                 float b_f = (float) z / 31.0;
3910
3911                 if(fmt == D3DFMT_A16B16G16R16) {
3912                     unsigned short *mem_s = mem;
3913                     mem_s[0]  = r_f * 65535.0;
3914                     mem_s[1]  = g_f * 65535.0;
3915                     mem_s[2]  = b_f * 65535.0;
3916                     mem_s[3]  = 65535;
3917                 } else {
3918                     unsigned char *mem_c = mem;
3919                     mem_c[0]  = b_f * 255.0;
3920                     mem_c[1]  = g_f * 255.0;
3921                     mem_c[2]  = r_f * 255.0;
3922                     mem_c[3]  = 255;
3923                 }
3924             }
3925         }
3926     }
3927     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3928     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3929
3930     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3931     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3932
3933     hr = IDirect3DDevice9_BeginScene(device);
3934     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3935     if(SUCCEEDED(hr))
3936     {
3937         float quad1[] = {
3938             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3939             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3940              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3941              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3942         };
3943         float quad2[] = {
3944             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3945             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3946              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3947              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3948         };
3949         float quad3[] = {
3950              0.0,       0.0,       0.1,     0.0,    0.0,
3951              0.0,       1.0,       0.1,     0.0,    0.0,
3952              1.0,       0.0,       0.1,     0.0,    0.0,
3953              1.0,       1.0,       0.1,     0.0,    0.0
3954         };
3955         float quad4[] = {
3956              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3957              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3958              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3959              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3960         };
3961         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3962                          0.0, 0.0, 1.0, 0.0,
3963                          0.0, 1.0, 0.0, 0.0,
3964                          0.0, 0.0, 0.0, 1.0};
3965         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3966         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3967
3968         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3969          * values
3970          */
3971         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3972         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3973         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3974         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3975         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3976         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3977
3978         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3979          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3980          * otherwise the w will be missing(blue).
3981          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3982          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3983          */
3984         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3985         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3986         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3987         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3988
3989         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
3990         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3991         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3992         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3993         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3994         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3995         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3996         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3997         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3998
3999         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4000          * disable. ATI extends it up to the amount of values needed for the volume texture
4001          */
4002         memset(mat, 0, sizeof(mat));
4003         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4004         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4005         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4006         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4007         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4008         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4009         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4010         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4011
4012         hr = IDirect3DDevice9_EndScene(device);
4013         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4014     }
4015
4016     color = getPixelColor(device, 160, 360);
4017     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4018     color = getPixelColor(device, 160, 120);
4019     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4020        "quad 2 has color %08x, expected 0x00ffff00\n", color);
4021     color = getPixelColor(device, 480, 120);
4022     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4023     color = getPixelColor(device, 480, 360);
4024     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4025
4026     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4027     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4028
4029     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4030     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4031     hr = IDirect3DDevice9_BeginScene(device);
4032     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4033     if(SUCCEEDED(hr))
4034     {
4035         float quad1[] = {
4036             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4037             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4038              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4039              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4040         };
4041         float quad2[] = {
4042             -1.0,       0.0,       0.1,
4043             -1.0,       1.0,       0.1,
4044              0.0,       0.0,       0.1,
4045              0.0,       1.0,       0.1,
4046         };
4047         float quad3[] = {
4048              0.0,       0.0,       0.1,     1.0,
4049              0.0,       1.0,       0.1,     1.0,
4050              1.0,       0.0,       0.1,     1.0,
4051              1.0,       1.0,       0.1,     1.0
4052         };
4053         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4054                            0.0, 0.0, 0.0, 0.0,
4055                            0.0, 0.0, 0.0, 0.0,
4056                            0.0, 1.0, 0.0, 0.0};
4057         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4058                            1.0, 0.0, 0.0, 0.0,
4059                            0.0, 1.0, 0.0, 0.0,
4060                            0.0, 0.0, 1.0, 0.0};
4061         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4062         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4063
4064         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4065          * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4066          * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4067          * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4068          * 4th *input* coordinate.
4069          */
4070         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4071         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4072         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4073         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4074         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4075         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4076
4077         /* None passed */
4078         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4079         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4080         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4081         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4082         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4083         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4084
4085         /* 4 used, 1 passed */
4086         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4087         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4088         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4089         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4090         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4091         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4092
4093         hr = IDirect3DDevice9_EndScene(device);
4094         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4095     }
4096     color = getPixelColor(device, 160, 360);
4097     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4098     color = getPixelColor(device, 160, 120);
4099     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4100     color = getPixelColor(device, 480, 120);
4101     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4102     /* Quad4: unused */
4103
4104     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4105     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4106
4107     IDirect3DVolumeTexture9_Release(volume);
4108
4109     out:
4110     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4111     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4112     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4113     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4114     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4115     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4116     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4117     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4118     IDirect3DVertexDeclaration9_Release(decl);
4119     IDirect3DVertexDeclaration9_Release(decl2);
4120     IDirect3DVertexDeclaration9_Release(decl3);
4121 }
4122
4123 static void texdepth_test(IDirect3DDevice9 *device)
4124 {
4125     IDirect3DPixelShader9 *shader;
4126     HRESULT hr;
4127     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4128     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4129     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4130     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4131     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4132     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4133     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4134     DWORD shader_code[] = {
4135         0xffff0104,                                                                 /* ps_1_4               */
4136         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4137         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4138         0x0000fffd,                                                                 /* phase                */
4139         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4140         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4141         0x0000ffff                                                                  /* end                  */
4142     };
4143     DWORD color;
4144     float vertex[] = {
4145        -1.0,   -1.0,    0.0,
4146         1.0,   -1.0,    1.0,
4147        -1.0,    1.0,    0.0,
4148         1.0,    1.0,    1.0
4149     };
4150
4151     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4152     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4153
4154     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4155     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4156     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4157     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4158     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4159     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4160     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4161     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4162     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4163     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4164
4165     /* Fill the depth buffer with a gradient */
4166     hr = IDirect3DDevice9_BeginScene(device);
4167     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4168     if(SUCCEEDED(hr))
4169     {
4170         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4171         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4172         hr = IDirect3DDevice9_EndScene(device);
4173         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4174     }
4175
4176     /* Now perform the actual tests. Same geometry, but with the shader */
4177     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4178     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4179     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4180     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4181     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4182     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4183
4184     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4185     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4186     hr = IDirect3DDevice9_BeginScene(device);
4187     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4188     if(SUCCEEDED(hr))
4189     {
4190         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4191         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4192
4193         hr = IDirect3DDevice9_EndScene(device);
4194         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4195     }
4196
4197     color = getPixelColor(device, 158, 240);
4198     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4199     color = getPixelColor(device, 162, 240);
4200     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4201
4202     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4203     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4204
4205     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4206     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4207
4208     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4209     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4210     hr = IDirect3DDevice9_BeginScene(device);
4211     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4212     if(SUCCEEDED(hr))
4213     {
4214         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4215         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4216
4217         hr = IDirect3DDevice9_EndScene(device);
4218         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4219     }
4220
4221     color = getPixelColor(device, 318, 240);
4222     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4223     color = getPixelColor(device, 322, 240);
4224     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4225
4226     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4227     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4228
4229     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4230     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4231
4232     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4233     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4234     hr = IDirect3DDevice9_BeginScene(device);
4235     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4236     if(SUCCEEDED(hr))
4237     {
4238         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4239         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4240
4241         hr = IDirect3DDevice9_EndScene(device);
4242         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4243     }
4244
4245     color = getPixelColor(device, 1, 240);
4246     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4247
4248     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4249     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4250
4251     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4252     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4253
4254     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4255     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4256     hr = IDirect3DDevice9_BeginScene(device);
4257     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4258     if(SUCCEEDED(hr))
4259     {
4260         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4261         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4262
4263         hr = IDirect3DDevice9_EndScene(device);
4264         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4265     }
4266     color = getPixelColor(device, 318, 240);
4267     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4268     color = getPixelColor(device, 322, 240);
4269     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4270
4271     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4272     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4273
4274     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4275     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4276
4277     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4278     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4279     hr = IDirect3DDevice9_BeginScene(device);
4280     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4281     if(SUCCEEDED(hr))
4282     {
4283         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4284         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4285
4286         hr = IDirect3DDevice9_EndScene(device);
4287         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4288     }
4289
4290     color = getPixelColor(device, 1, 240);
4291     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4292
4293     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4294     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4295
4296     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4297     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4298
4299     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4300     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4301     hr = IDirect3DDevice9_BeginScene(device);
4302     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4303     if(SUCCEEDED(hr))
4304     {
4305         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4306         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4307
4308         hr = IDirect3DDevice9_EndScene(device);
4309         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4310     }
4311
4312     color = getPixelColor(device, 638, 240);
4313     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4314
4315     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4316     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4317
4318     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4319     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4320
4321     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4322     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4323     hr = IDirect3DDevice9_BeginScene(device);
4324     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4325     if(SUCCEEDED(hr))
4326     {
4327         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4328         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4329
4330         hr = IDirect3DDevice9_EndScene(device);
4331         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4332     }
4333
4334     color = getPixelColor(device, 638, 240);
4335     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4336
4337     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4338     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4339
4340     /* Cleanup */
4341     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4342     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4343     IDirect3DPixelShader9_Release(shader);
4344
4345     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4346     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4347     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4348     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4349 }
4350
4351 static void texkill_test(IDirect3DDevice9 *device)
4352 {
4353     IDirect3DPixelShader9 *shader;
4354     HRESULT hr;
4355     DWORD color;
4356
4357     const float vertex[] = {
4358     /*                          bottom  top    right    left */
4359         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4360          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4361         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4362          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4363     };
4364
4365     DWORD shader_code_11[] = {
4366     0xffff0101,                                                             /* ps_1_1                     */
4367     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4368     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4369     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4370     0x0000ffff                                                              /* end                        */
4371     };
4372     DWORD shader_code_20[] = {
4373     0xffff0200,                                                             /* ps_2_0                     */
4374     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4375     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4376     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4377     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4378     0x0000ffff                                                              /* end                        */
4379     };
4380
4381     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4382     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4383     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4384     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4385
4386     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4387     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4388     hr = IDirect3DDevice9_BeginScene(device);
4389     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4390     if(SUCCEEDED(hr))
4391     {
4392         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4393         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4394         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4395         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4396         hr = IDirect3DDevice9_EndScene(device);
4397         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4398     }
4399     color = getPixelColor(device, 63, 46);
4400     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4401     color = getPixelColor(device, 66, 46);
4402     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4403     color = getPixelColor(device, 63, 49);
4404     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4405     color = getPixelColor(device, 66, 49);
4406     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4407
4408     color = getPixelColor(device, 578, 46);
4409     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4410     color = getPixelColor(device, 575, 46);
4411     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4412     color = getPixelColor(device, 578, 49);
4413     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4414     color = getPixelColor(device, 575, 49);
4415     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4416
4417     color = getPixelColor(device, 63, 430);
4418     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4419     color = getPixelColor(device, 63, 433);
4420     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4421     color = getPixelColor(device, 66, 433);
4422     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4423     color = getPixelColor(device, 66, 430);
4424     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4425
4426     color = getPixelColor(device, 578, 430);
4427     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4428     color = getPixelColor(device, 578, 433);
4429     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4430     color = getPixelColor(device, 575, 433);
4431     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4432     color = getPixelColor(device, 575, 430);
4433     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4434
4435     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4436     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4437
4438     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4439     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4440     IDirect3DPixelShader9_Release(shader);
4441
4442     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4443     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4444     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4445     if(FAILED(hr)) {
4446         skip("Failed to create 2.0 test shader, most likely not supported\n");
4447         return;
4448     }
4449
4450     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4451     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4452     hr = IDirect3DDevice9_BeginScene(device);
4453     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4454     if(SUCCEEDED(hr))
4455     {
4456         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4457         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4458         hr = IDirect3DDevice9_EndScene(device);
4459         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4460     }
4461
4462     color = getPixelColor(device, 63, 46);
4463     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4464     color = getPixelColor(device, 66, 46);
4465     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4466     color = getPixelColor(device, 63, 49);
4467     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4468     color = getPixelColor(device, 66, 49);
4469     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4470
4471     color = getPixelColor(device, 578, 46);
4472     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4473     color = getPixelColor(device, 575, 46);
4474     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4475     color = getPixelColor(device, 578, 49);
4476     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4477     color = getPixelColor(device, 575, 49);
4478     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4479
4480     color = getPixelColor(device, 63, 430);
4481     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4482     color = getPixelColor(device, 63, 433);
4483     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4484     color = getPixelColor(device, 66, 433);
4485     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4486     color = getPixelColor(device, 66, 430);
4487     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4488
4489     color = getPixelColor(device, 578, 430);
4490     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4491     color = getPixelColor(device, 578, 433);
4492     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4493     color = getPixelColor(device, 575, 433);
4494     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4495     color = getPixelColor(device, 575, 430);
4496     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4497
4498     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4499     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4500
4501     /* Cleanup */
4502     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4503     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4504     IDirect3DPixelShader9_Release(shader);
4505 }
4506
4507 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4508 {
4509     IDirect3D9 *d3d9;
4510     HRESULT hr;
4511     IDirect3DTexture9 *texture;
4512     IDirect3DPixelShader9 *shader;
4513     IDirect3DPixelShader9 *shader2;
4514     D3DLOCKED_RECT lr;
4515     DWORD color;
4516     DWORD shader_code[] = {
4517         0xffff0101,                             /* ps_1_1       */
4518         0x00000042, 0xb00f0000,                 /* tex t0       */
4519         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4520         0x0000ffff                              /* end          */
4521     };
4522     DWORD shader_code2[] = {
4523         0xffff0101,                             /* ps_1_1       */
4524         0x00000042, 0xb00f0000,                 /* tex t0       */
4525         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4526         0x0000ffff                              /* end          */
4527     };
4528
4529     float quad[] = {
4530        -1.0,   -1.0,   0.1,     0.5,    0.5,
4531         1.0,   -1.0,   0.1,     0.5,    0.5,
4532        -1.0,    1.0,   0.1,     0.5,    0.5,
4533         1.0,    1.0,   0.1,     0.5,    0.5,
4534     };
4535
4536     memset(&lr, 0, sizeof(lr));
4537     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4538     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4539                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4540     IDirect3D9_Release(d3d9);
4541     if(FAILED(hr)) {
4542         skip("No D3DFMT_X8L8V8U8 support\n");
4543         return;
4544     };
4545
4546     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4547     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4548
4549     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4550     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4551     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4552     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4553     *((DWORD *) lr.pBits) = 0x11ca3141;
4554     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4555     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4556
4557     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4558     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4559     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4560     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4561
4562     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4563     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4564     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4565     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4566     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4567     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4568
4569     hr = IDirect3DDevice9_BeginScene(device);
4570     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4571     if(SUCCEEDED(hr))
4572     {
4573         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4574         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4575
4576         hr = IDirect3DDevice9_EndScene(device);
4577         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4578     }
4579     color = getPixelColor(device, 578, 430);
4580     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4581        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4582     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4583     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4584
4585     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4586     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4587     hr = IDirect3DDevice9_BeginScene(device);
4588     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4589     if(SUCCEEDED(hr))
4590     {
4591         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4592         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4593
4594         hr = IDirect3DDevice9_EndScene(device);
4595         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4596     }
4597     color = getPixelColor(device, 578, 430);
4598     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4599     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4600     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4601
4602     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4603     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4604     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4605     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4606     IDirect3DPixelShader9_Release(shader);
4607     IDirect3DPixelShader9_Release(shader2);
4608     IDirect3DTexture9_Release(texture);
4609 }
4610
4611 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4612 {
4613     HRESULT hr;
4614     IDirect3D9 *d3d;
4615     IDirect3DTexture9 *texture = NULL;
4616     IDirect3DSurface9 *surface;
4617     DWORD color;
4618     const RECT r1 = {256, 256, 512, 512};
4619     const RECT r2 = {512, 256, 768, 512};
4620     const RECT r3 = {256, 512, 512, 768};
4621     const RECT r4 = {512, 512, 768, 768};
4622     unsigned int x, y;
4623     D3DLOCKED_RECT lr;
4624     memset(&lr, 0, sizeof(lr));
4625
4626     IDirect3DDevice9_GetDirect3D(device, &d3d);
4627     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4628        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4629         skip("No autogenmipmap support\n");
4630         IDirect3D9_Release(d3d);
4631         return;
4632     }
4633     IDirect3D9_Release(d3d);
4634
4635     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4636     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4637
4638     /* Make the mipmap big, so that a smaller mipmap is used
4639      */
4640     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4641                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4642     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4643
4644     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4645     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4646     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4647     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4648     for(y = 0; y < 1024; y++) {
4649         for(x = 0; x < 1024; x++) {
4650             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4651             POINT pt;
4652
4653             pt.x = x;
4654             pt.y = y;
4655             if(PtInRect(&r1, pt)) {
4656                 *dst = 0xffff0000;
4657             } else if(PtInRect(&r2, pt)) {
4658                 *dst = 0xff00ff00;
4659             } else if(PtInRect(&r3, pt)) {
4660                 *dst = 0xff0000ff;
4661             } else if(PtInRect(&r4, pt)) {
4662                 *dst = 0xff000000;
4663             } else {
4664                 *dst = 0xffffffff;
4665             }
4666         }
4667     }
4668     hr = IDirect3DSurface9_UnlockRect(surface);
4669     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4670     IDirect3DSurface9_Release(surface);
4671
4672     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4673     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4674     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4675     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4676
4677     hr = IDirect3DDevice9_BeginScene(device);
4678     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4679     if(SUCCEEDED(hr)) {
4680         const float quad[] =  {
4681            -0.5,   -0.5,    0.1,    0.0,    0.0,
4682            -0.5,    0.5,    0.1,    0.0,    1.0,
4683             0.5,   -0.5,    0.1,    1.0,    0.0,
4684             0.5,    0.5,    0.1,    1.0,    1.0
4685         };
4686
4687         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4688         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4689         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4690         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4691         hr = IDirect3DDevice9_EndScene(device);
4692         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4693     }
4694     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4695     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4696     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4697     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4698     IDirect3DTexture9_Release(texture);
4699
4700     color = getPixelColor(device, 200, 200);
4701     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4702     color = getPixelColor(device, 280, 200);
4703     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4704     color = getPixelColor(device, 360, 200);
4705     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4706     color = getPixelColor(device, 440, 200);
4707     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4708     color = getPixelColor(device, 200, 270);
4709     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4710     color = getPixelColor(device, 280, 270);
4711     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4712     color = getPixelColor(device, 360, 270);
4713     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4714     color = getPixelColor(device, 440, 270);
4715     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4716     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4717     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4718 }
4719
4720 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4721 {
4722     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4723     IDirect3DVertexDeclaration9 *decl;
4724     HRESULT hr;
4725     DWORD color;
4726     DWORD shader_code_11[] =  {
4727         0xfffe0101,                                         /* vs_1_1           */
4728         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4729         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4730         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4731         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4732         0x0000ffff                                          /* end              */
4733     };
4734     DWORD shader_code_11_2[] =  {
4735         0xfffe0101,                                         /* vs_1_1           */
4736         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4737         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4738         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4739         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4740         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4741         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4742         0x0000ffff                                          /* end              */
4743     };
4744     DWORD shader_code_20[] =  {
4745         0xfffe0200,                                         /* vs_2_0           */
4746         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4747         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4748         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4749         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4750         0x0000ffff                                          /* end              */
4751     };
4752     DWORD shader_code_20_2[] =  {
4753         0xfffe0200,                                         /* vs_2_0           */
4754         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4755         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4756         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4757         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4758         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4759         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4760         0x0000ffff                                          /* end              */
4761     };
4762     static const D3DVERTEXELEMENT9 decl_elements[] = {
4763         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4764         D3DDECL_END()
4765     };
4766     float quad1[] = {
4767         -1.0,   -1.0,   0.1,
4768          0.0,   -1.0,   0.1,
4769         -1.0,    0.0,   0.1,
4770          0.0,    0.0,   0.1
4771     };
4772     float quad2[] = {
4773          0.0,   -1.0,   0.1,
4774          1.0,   -1.0,   0.1,
4775          0.0,    0.0,   0.1,
4776          1.0,    0.0,   0.1
4777     };
4778     float quad3[] = {
4779          0.0,    0.0,   0.1,
4780          1.0,    0.0,   0.1,
4781          0.0,    1.0,   0.1,
4782          1.0,    1.0,   0.1
4783     };
4784     float quad4[] = {
4785         -1.0,    0.0,   0.1,
4786          0.0,    0.0,   0.1,
4787         -1.0,    1.0,   0.1,
4788          0.0,    1.0,   0.1
4789     };
4790     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4791     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4792
4793     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4794     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4795
4796     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4797     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4798     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4799     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4800     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4801     if(FAILED(hr)) shader_20 = NULL;
4802     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4803     if(FAILED(hr)) shader_20_2 = NULL;
4804     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4805     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4806
4807     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4808     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4809     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4810     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4811     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4812     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4813
4814     hr = IDirect3DDevice9_BeginScene(device);
4815     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4816     if(SUCCEEDED(hr))
4817     {
4818         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4819         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4820         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4821         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4822
4823         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4824         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4825         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4826         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4827
4828         if(shader_20) {
4829             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4830             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4831             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4832             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4833         }
4834
4835         if(shader_20_2) {
4836             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4837             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4838             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4839             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4840         }
4841
4842         hr = IDirect3DDevice9_EndScene(device);
4843         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4844     }
4845
4846     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4847     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4848     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4849     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4850
4851     color = getPixelColor(device, 160, 360);
4852     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4853        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4854     color = getPixelColor(device, 480, 360);
4855     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4856        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4857     if(shader_20) {
4858         color = getPixelColor(device, 480, 120);
4859         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4860            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4861     }
4862     if(shader_20_2) {
4863         color = getPixelColor(device, 160, 120);
4864         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4865            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4866     }
4867     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4868     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4869
4870     IDirect3DVertexDeclaration9_Release(decl);
4871     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4872     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4873     IDirect3DVertexShader9_Release(shader_11_2);
4874     IDirect3DVertexShader9_Release(shader_11);
4875 }
4876
4877 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4878 {
4879     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4880     HRESULT hr;
4881     DWORD color;
4882     DWORD shader_code_11[] =  {
4883         0xffff0101,                                         /* ps_1_1           */
4884         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4885         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4886         0x0000ffff                                          /* end              */
4887     };
4888     DWORD shader_code_12[] =  {
4889         0xffff0102,                                         /* ps_1_2           */
4890         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4891         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4892         0x0000ffff                                          /* end              */
4893     };
4894     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4895      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4896      * During development of this test, 1.3 shaders were verified too
4897      */
4898     DWORD shader_code_14[] =  {
4899         0xffff0104,                                         /* ps_1_4           */
4900         /* Try to make one constant local. It gets clamped too, although the binary contains
4901          * the bigger numbers
4902          */
4903         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4904         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4905         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4906         0x0000ffff                                          /* end              */
4907     };
4908     DWORD shader_code_20[] =  {
4909         0xffff0200,                                         /* ps_2_0           */
4910         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4911         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4912         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4913         0x0000ffff                                          /* end              */
4914     };
4915     float quad1[] = {
4916         -1.0,   -1.0,   0.1,
4917          0.0,   -1.0,   0.1,
4918         -1.0,    0.0,   0.1,
4919          0.0,    0.0,   0.1
4920     };
4921     float quad2[] = {
4922          0.0,   -1.0,   0.1,
4923          1.0,   -1.0,   0.1,
4924          0.0,    0.0,   0.1,
4925          1.0,    0.0,   0.1
4926     };
4927     float quad3[] = {
4928          0.0,    0.0,   0.1,
4929          1.0,    0.0,   0.1,
4930          0.0,    1.0,   0.1,
4931          1.0,    1.0,   0.1
4932     };
4933     float quad4[] = {
4934         -1.0,    0.0,   0.1,
4935          0.0,    0.0,   0.1,
4936         -1.0,    1.0,   0.1,
4937          0.0,    1.0,   0.1
4938     };
4939     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4940     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4941
4942     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4943     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4944
4945     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4946     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4947     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4948     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4949     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4950     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4951     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4952     if(FAILED(hr)) shader_20 = NULL;
4953
4954     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4955     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4956     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4957     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4958     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4959     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4960
4961     hr = IDirect3DDevice9_BeginScene(device);
4962     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4963     if(SUCCEEDED(hr))
4964     {
4965         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4966         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4967         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4968         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4969
4970         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4971         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4972         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4973         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4974
4975         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4976         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4977         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4978         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4979
4980         if(shader_20) {
4981             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4982             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4983             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4984             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4985         }
4986
4987         hr = IDirect3DDevice9_EndScene(device);
4988         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4989     }
4990     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4991     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4992
4993     color = getPixelColor(device, 160, 360);
4994     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4995        "quad 1 has color %08x, expected 0x00808000\n", color);
4996     color = getPixelColor(device, 480, 360);
4997     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4998        "quad 2 has color %08x, expected 0x00808000\n", color);
4999     color = getPixelColor(device, 480, 120);
5000     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5001        "quad 3 has color %08x, expected 0x00808000\n", color);
5002     if(shader_20) {
5003         color = getPixelColor(device, 160, 120);
5004         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5005            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5006     }
5007     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5008     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5009
5010     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5011     IDirect3DPixelShader9_Release(shader_14);
5012     IDirect3DPixelShader9_Release(shader_12);
5013     IDirect3DPixelShader9_Release(shader_11);
5014 }
5015
5016 static void dp2add_ps_test(IDirect3DDevice9 *device)
5017 {
5018     IDirect3DPixelShader9 *shader_dp2add = NULL;
5019     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5020     HRESULT hr;
5021     DWORD color;
5022
5023     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
5024      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5025      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
5026      * r0 first.
5027      * The result here for the r,g,b components should be roughly 0.5:
5028      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5029     static const DWORD shader_code_dp2add[] =  {
5030         0xffff0200,                                                             /* ps_2_0                       */
5031         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
5032
5033         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5034         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
5035
5036         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
5037         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5038         0x0000ffff                                                              /* end                          */
5039     };
5040
5041     /* Test the _sat modifier, too.  Result here should be:
5042      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5043      *      _SAT: ==> 1.0
5044      *   ADD: (1.0 + -0.5) = 0.5
5045      */
5046     static const DWORD shader_code_dp2add_sat[] =  {
5047         0xffff0200,                                                             /* ps_2_0                           */
5048         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
5049
5050         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
5051         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
5052         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5053
5054         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5055         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5056         0x0000ffff                                                              /* end                              */
5057     };
5058
5059     const float quad[] = {
5060         -1.0,   -1.0,   0.1,
5061          1.0,   -1.0,   0.1,
5062         -1.0,    1.0,   0.1,
5063          1.0,    1.0,   0.1
5064     };
5065
5066
5067     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5068     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5069
5070     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5071     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5072
5073     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5074     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5075
5076     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5077     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5078
5079     if (shader_dp2add) {
5080
5081         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5082         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5083
5084         hr = IDirect3DDevice9_BeginScene(device);
5085         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5086         if(SUCCEEDED(hr))
5087         {
5088             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5089             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5090
5091             hr = IDirect3DDevice9_EndScene(device);
5092             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5093         }
5094
5095         color = getPixelColor(device, 360, 240);
5096         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5097                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5098
5099         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5100         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5101
5102         IDirect3DPixelShader9_Release(shader_dp2add);
5103     } else {
5104         skip("dp2add shader creation failed\n");
5105     }
5106
5107     if (shader_dp2add_sat) {
5108
5109         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5110         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5111
5112         hr = IDirect3DDevice9_BeginScene(device);
5113         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5114         if(SUCCEEDED(hr))
5115         {
5116             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5117             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5118
5119             hr = IDirect3DDevice9_EndScene(device);
5120             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5121         }
5122
5123         color = getPixelColor(device, 360, 240);
5124         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5125                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5126
5127         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5128         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5129
5130         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5131     } else {
5132         skip("dp2add shader creation failed\n");
5133     }
5134
5135     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5136     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5137 }
5138
5139 static void cnd_test(IDirect3DDevice9 *device)
5140 {
5141     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5142     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5143     HRESULT hr;
5144     DWORD color;
5145     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5146      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5147      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5148      */
5149     DWORD shader_code_11[] =  {
5150         0xffff0101,                                                                 /* ps_1_1               */
5151         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5152         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5153         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5154         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5155         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5156         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5157         0x0000ffff                                                                  /* end                  */
5158     };
5159     DWORD shader_code_12[] =  {
5160         0xffff0102,                                                                 /* ps_1_2               */
5161         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5162         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5163         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5164         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5165         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5166         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5167         0x0000ffff                                                                  /* end                  */
5168     };
5169     DWORD shader_code_13[] =  {
5170         0xffff0103,                                                                 /* ps_1_3               */
5171         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5172         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5173         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5174         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5175         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5176         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5177         0x0000ffff                                                                  /* end                  */
5178     };
5179     DWORD shader_code_14[] =  {
5180         0xffff0104,                                                                 /* ps_1_3               */
5181         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5182         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5183         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5184         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5185         0x0000ffff                                                                  /* end                  */
5186     };
5187
5188     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5189      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5190      * set by the compiler, it was added manually after compilation. Note that the COISSUE
5191      * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5192      * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5193      * well enough.
5194      *
5195      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5196      * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5197      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5198      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5199      */
5200     DWORD shader_code_11_coissue[] =  {
5201         0xffff0101,                                                             /* ps_1_1                   */
5202         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5203         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5204         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5205         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5206         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5207         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5208         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5209         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5210         /* 0x40000000 = D3DSI_COISSUE */
5211         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5212         0x0000ffff                                                              /* end                      */
5213     };
5214     DWORD shader_code_12_coissue[] =  {
5215         0xffff0102,                                                             /* ps_1_2                   */
5216         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5217         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5218         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5219         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5220         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5221         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5222         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5223         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5224         /* 0x40000000 = D3DSI_COISSUE */
5225         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5226         0x0000ffff                                                              /* end                      */
5227     };
5228     DWORD shader_code_13_coissue[] =  {
5229         0xffff0103,                                                             /* ps_1_3                   */
5230         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5231         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5232         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5233         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5234         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5235         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5236         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5237         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5238         /* 0x40000000 = D3DSI_COISSUE */
5239         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5240         0x0000ffff                                                              /* end                      */
5241     };
5242     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5243      * compare against 0.5
5244      */
5245     DWORD shader_code_14_coissue[] =  {
5246         0xffff0104,                                                             /* ps_1_4                   */
5247         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5248         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5249         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5250         /* 0x40000000 = D3DSI_COISSUE */
5251         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5252         0x0000ffff                                                              /* end                      */
5253     };
5254     float quad1[] = {
5255         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5256          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5257         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5258          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5259     };
5260     float quad2[] = {
5261          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5262          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5263          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5264          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5265     };
5266     float quad3[] = {
5267          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5268          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5269          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5270          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5271     };
5272     float quad4[] = {
5273         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5274          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5275         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5276          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5277     };
5278     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5279     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5280     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5281     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5282
5283     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5284     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5285
5286     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5287     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5288     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5289     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5290     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5291     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5292     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5293     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5294     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5295     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5296     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5297     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5298     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5299     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5300     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5301     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5302
5303     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5304     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5305     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5306     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5307     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5308     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5309
5310     hr = IDirect3DDevice9_BeginScene(device);
5311     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5312     if(SUCCEEDED(hr))
5313     {
5314         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5315         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5316         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5317         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5318
5319         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5320         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5321         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5322         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5323
5324         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5325         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5326         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5327         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5328
5329         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5330         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5331         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5332         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5333
5334         hr = IDirect3DDevice9_EndScene(device);
5335         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5336     }
5337
5338     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5339     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5340
5341     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5342     color = getPixelColor(device, 158, 118);
5343     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5344     color = getPixelColor(device, 162, 118);
5345     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5346     color = getPixelColor(device, 158, 122);
5347     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5348     color = getPixelColor(device, 162, 122);
5349     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5350
5351     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5352     color = getPixelColor(device, 158, 358);
5353     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5354     color = getPixelColor(device, 162, 358);
5355     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5356         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5357     color = getPixelColor(device, 158, 362);
5358     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5359     color = getPixelColor(device, 162, 362);
5360     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5361         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5362
5363     /* 1.2 shader */
5364     color = getPixelColor(device, 478, 358);
5365     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5366     color = getPixelColor(device, 482, 358);
5367     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5368         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5369     color = getPixelColor(device, 478, 362);
5370     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5371     color = getPixelColor(device, 482, 362);
5372     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5373         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5374
5375     /* 1.3 shader */
5376     color = getPixelColor(device, 478, 118);
5377     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5378     color = getPixelColor(device, 482, 118);
5379     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5380         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5381     color = getPixelColor(device, 478, 122);
5382     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5383     color = getPixelColor(device, 482, 122);
5384     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5385         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5386
5387     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5388     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5389
5390     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5391     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5392     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5393     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5394     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5395     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5396
5397     hr = IDirect3DDevice9_BeginScene(device);
5398     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5399     if(SUCCEEDED(hr))
5400     {
5401         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5402         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5403         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5404         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5405
5406         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5407         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5408         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5409         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5410
5411         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5412         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5413         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5414         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5415
5416         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5417         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5418         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5419         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5420
5421         hr = IDirect3DDevice9_EndScene(device);
5422         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5423     }
5424
5425     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5426     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5427
5428     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5429      * that we swapped the values in c1 and c2 to make the other tests return some color
5430      */
5431     color = getPixelColor(device, 158, 118);
5432     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5433     color = getPixelColor(device, 162, 118);
5434     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5435     color = getPixelColor(device, 158, 122);
5436     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5437     color = getPixelColor(device, 162, 122);
5438     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5439
5440     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5441      * (The Win7 nvidia driver always selects c2)
5442      */
5443     color = getPixelColor(device, 158, 358);
5444     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5445         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5446     color = getPixelColor(device, 162, 358);
5447     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5448         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5449     color = getPixelColor(device, 158, 362);
5450     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5451         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5452     color = getPixelColor(device, 162, 362);
5453     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5454         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5455
5456     /* 1.2 shader */
5457     color = getPixelColor(device, 478, 358);
5458     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5459         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5460     color = getPixelColor(device, 482, 358);
5461     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5462         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5463     color = getPixelColor(device, 478, 362);
5464     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5465         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5466     color = getPixelColor(device, 482, 362);
5467     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5468         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5469
5470     /* 1.3 shader */
5471     color = getPixelColor(device, 478, 118);
5472     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5473         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5474     color = getPixelColor(device, 482, 118);
5475     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5476         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5477     color = getPixelColor(device, 478, 122);
5478     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5479         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5480     color = getPixelColor(device, 482, 122);
5481     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5482         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5483
5484     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5485     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5486
5487     IDirect3DPixelShader9_Release(shader_14_coissue);
5488     IDirect3DPixelShader9_Release(shader_13_coissue);
5489     IDirect3DPixelShader9_Release(shader_12_coissue);
5490     IDirect3DPixelShader9_Release(shader_11_coissue);
5491     IDirect3DPixelShader9_Release(shader_14);
5492     IDirect3DPixelShader9_Release(shader_13);
5493     IDirect3DPixelShader9_Release(shader_12);
5494     IDirect3DPixelShader9_Release(shader_11);
5495 }
5496
5497 static void nested_loop_test(IDirect3DDevice9 *device) {
5498     const DWORD shader_code[] = {
5499         0xffff0300,                                                             /* ps_3_0               */
5500         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5501         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5502         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5503         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5504         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5505         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5506         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5507         0x0000001d,                                                             /* endloop              */
5508         0x0000001d,                                                             /* endloop              */
5509         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5510         0x0000ffff                                                              /* end                  */
5511     };
5512     const DWORD vshader_code[] = {
5513         0xfffe0300,                                                             /* vs_3_0               */
5514         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
5515         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
5516         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
5517         0x0000ffff                                                              /* end                  */
5518     };
5519     IDirect3DPixelShader9 *shader;
5520     IDirect3DVertexShader9 *vshader;
5521     HRESULT hr;
5522     DWORD color;
5523     const float quad[] = {
5524         -1.0,   -1.0,   0.1,
5525          1.0,   -1.0,   0.1,
5526         -1.0,    1.0,   0.1,
5527          1.0,    1.0,   0.1
5528     };
5529
5530     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5531     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5532     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5533     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5534     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5535     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5536     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5537     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5538     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5539     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5540     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5541     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5542
5543     hr = IDirect3DDevice9_BeginScene(device);
5544     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5545     if(SUCCEEDED(hr))
5546     {
5547         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5548         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5549         hr = IDirect3DDevice9_EndScene(device);
5550         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5551     }
5552
5553     color = getPixelColor(device, 360, 240);
5554     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5555        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5556
5557     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5558     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5559
5560     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5561     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5562     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5563     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5564     IDirect3DPixelShader9_Release(shader);
5565     IDirect3DVertexShader9_Release(vshader);
5566 }
5567
5568 struct varying_test_struct
5569 {
5570     const DWORD             *shader_code;
5571     IDirect3DPixelShader9   *shader;
5572     DWORD                   color, color_rhw;
5573     const char              *name;
5574     BOOL                    todo, todo_rhw;
5575 };
5576
5577 struct hugeVertex
5578 {
5579     float pos_x,        pos_y,      pos_z,      rhw;
5580     float weight_1,     weight_2,   weight_3,   weight_4;
5581     float index_1,      index_2,    index_3,    index_4;
5582     float normal_1,     normal_2,   normal_3,   normal_4;
5583     float fog_1,        fog_2,      fog_3,      fog_4;
5584     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5585     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5586     float binormal_1,   binormal_2, binormal_3, binormal_4;
5587     float depth_1,      depth_2,    depth_3,    depth_4;
5588     DWORD diffuse, specular;
5589 };
5590
5591 static void pretransformed_varying_test(IDirect3DDevice9 *device) {
5592     /* dcl_position: fails to compile */
5593     const DWORD blendweight_code[] = {
5594         0xffff0300,                             /* ps_3_0                   */
5595         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5596         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5597         0x0000ffff                              /* end                      */
5598     };
5599     const DWORD blendindices_code[] = {
5600         0xffff0300,                             /* ps_3_0                   */
5601         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5602         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5603         0x0000ffff                              /* end                      */
5604     };
5605     const DWORD normal_code[] = {
5606         0xffff0300,                             /* ps_3_0                   */
5607         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5608         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5609         0x0000ffff                              /* end                      */
5610     };
5611     /* psize: fails? */
5612     const DWORD texcoord0_code[] = {
5613         0xffff0300,                             /* ps_3_0                   */
5614         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5615         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5616         0x0000ffff                              /* end                      */
5617     };
5618     const DWORD tangent_code[] = {
5619         0xffff0300,                             /* ps_3_0                   */
5620         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5621         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5622         0x0000ffff                              /* end                      */
5623     };
5624     const DWORD binormal_code[] = {
5625         0xffff0300,                             /* ps_3_0                   */
5626         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5627         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5628         0x0000ffff                              /* end                      */
5629     };
5630     /* tessfactor: fails */
5631     /* positiont: fails */
5632     const DWORD color_code[] = {
5633         0xffff0300,                             /* ps_3_0                   */
5634         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5635         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5636         0x0000ffff                              /* end                      */
5637     };
5638     const DWORD fog_code[] = {
5639         0xffff0300,                             /* ps_3_0                   */
5640         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5641         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5642         0x0000ffff                              /* end                      */
5643     };
5644     const DWORD depth_code[] = {
5645         0xffff0300,                             /* ps_3_0                   */
5646         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5647         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5648         0x0000ffff                              /* end                      */
5649     };
5650     const DWORD specular_code[] = {
5651         0xffff0300,                             /* ps_3_0                   */
5652         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5653         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5654         0x0000ffff                              /* end                      */
5655     };
5656     /* sample: fails */
5657
5658     struct varying_test_struct tests[] = {
5659        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5660        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5661        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5662        /* Why does dx not forward the texcoord? */
5663        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5664        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5665        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5666        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5667        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5668        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5669        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5670     };
5671     /* Declare a monster vertex type :-) */
5672     static const D3DVERTEXELEMENT9 decl_elements[] = {
5673         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5674         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5675         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5676         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5677         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5678         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5679         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5680         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5681         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5682         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5683         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5684         D3DDECL_END()
5685     };
5686     struct hugeVertex data[4] = {
5687         {
5688             -1.0,   -1.0,   0.1,    1.0,
5689              0.1,    0.1,   0.1,    0.1,
5690              0.2,    0.2,   0.2,    0.2,
5691              0.3,    0.3,   0.3,    0.3,
5692              0.4,    0.4,   0.4,    0.4,
5693              0.50,   0.55,  0.55,   0.55,
5694              0.6,    0.6,   0.6,    0.7,
5695              0.7,    0.7,   0.7,    0.6,
5696              0.8,    0.8,   0.8,    0.8,
5697              0xe6e6e6e6, /* 0.9 * 256 */
5698              0x224488ff  /* Nothing special */
5699         },
5700         {
5701              1.0,   -1.0,   0.1,    1.0,
5702              0.1,    0.1,   0.1,    0.1,
5703              0.2,    0.2,   0.2,    0.2,
5704              0.3,    0.3,   0.3,    0.3,
5705              0.4,    0.4,   0.4,    0.4,
5706              0.50,   0.55,  0.55,   0.55,
5707              0.6,    0.6,   0.6,    0.7,
5708              0.7,    0.7,   0.7,    0.6,
5709              0.8,    0.8,   0.8,    0.8,
5710              0xe6e6e6e6, /* 0.9 * 256 */
5711              0x224488ff /* Nothing special */
5712         },
5713         {
5714             -1.0,    1.0,   0.1,    1.0,
5715              0.1,    0.1,   0.1,    0.1,
5716              0.2,    0.2,   0.2,    0.2,
5717              0.3,    0.3,   0.3,    0.3,
5718              0.4,    0.4,   0.4,    0.4,
5719              0.50,   0.55,  0.55,   0.55,
5720              0.6,    0.6,   0.6,    0.7,
5721              0.7,    0.7,   0.7,    0.6,
5722              0.8,    0.8,   0.8,    0.8,
5723              0xe6e6e6e6, /* 0.9 * 256 */
5724              0x224488ff /* Nothing special */
5725         },
5726         {
5727              1.0,    1.0,   0.1,    1.0,
5728              0.1,    0.1,   0.1,    0.1,
5729              0.2,    0.2,   0.2,    0.2,
5730              0.3,    0.3,   0.3,    0.3,
5731              0.4,    0.4,   0.4,    0.4,
5732              0.50,   0.55,  0.55,   0.55,
5733              0.6,    0.6,   0.6,    0.7,
5734              0.7,    0.7,   0.7,    0.6,
5735              0.8,    0.8,   0.8,    0.8,
5736              0xe6e6e6e6, /* 0.9 * 256 */
5737              0x224488ff /* Nothing special */
5738         },
5739     };
5740     struct hugeVertex data2[4];
5741     IDirect3DVertexDeclaration9 *decl;
5742     HRESULT hr;
5743     unsigned int i;
5744     DWORD color, r, g, b, r_e, g_e, b_e;
5745
5746     memcpy(data2, data, sizeof(data2));
5747     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5748     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5749     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5750     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5751
5752     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5753     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5754     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5755     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5756
5757     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5758     {
5759         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5760         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5761            tests[i].name, hr);
5762     }
5763
5764     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5765     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5766     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5767     {
5768         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5769         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5770
5771         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5772         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5773
5774         hr = IDirect3DDevice9_BeginScene(device);
5775         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5776         if(SUCCEEDED(hr))
5777         {
5778             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5779             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5780             hr = IDirect3DDevice9_EndScene(device);
5781             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5782         }
5783
5784         color = getPixelColor(device, 360, 240);
5785         r = color & 0x00ff0000 >> 16;
5786         g = color & 0x0000ff00 >>  8;
5787         b = color & 0x000000ff;
5788         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5789         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5790         b_e = tests[i].color_rhw & 0x000000ff;
5791
5792         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5793         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5794
5795         if(tests[i].todo_rhw) {
5796             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5797              * pipeline
5798              */
5799             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5800                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5801                          tests[i].name, color, tests[i].color_rhw);
5802         } else {
5803             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5804                "Test %s returned color 0x%08x, expected 0x%08x\n",
5805                tests[i].name, color, tests[i].color_rhw);
5806         }
5807     }
5808
5809     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5810     {
5811         IDirect3DPixelShader9_Release(tests[i].shader);
5812     }
5813
5814     IDirect3DVertexDeclaration9_Release(decl);
5815 }
5816
5817 static void test_compare_instructions(IDirect3DDevice9 *device)
5818 {
5819     DWORD shader_sge_vec_code[] = {
5820         0xfffe0101,                                         /* vs_1_1                   */
5821         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5822         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5823         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5824         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5825         0x0000ffff                                          /* end                      */
5826     };
5827     DWORD shader_slt_vec_code[] = {
5828         0xfffe0101,                                         /* vs_1_1                   */
5829         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5830         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5831         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5832         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5833         0x0000ffff                                          /* end                      */
5834     };
5835     DWORD shader_sge_scalar_code[] = {
5836         0xfffe0101,                                         /* vs_1_1                   */
5837         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5838         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5839         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5840         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5841         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5842         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5843         0x0000ffff                                          /* end                      */
5844     };
5845     DWORD shader_slt_scalar_code[] = {
5846         0xfffe0101,                                         /* vs_1_1                   */
5847         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5848         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5849         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5850         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5851         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5852         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5853         0x0000ffff                                          /* end                      */
5854     };
5855     IDirect3DVertexShader9 *shader_sge_vec;
5856     IDirect3DVertexShader9 *shader_slt_vec;
5857     IDirect3DVertexShader9 *shader_sge_scalar;
5858     IDirect3DVertexShader9 *shader_slt_scalar;
5859     HRESULT hr, color;
5860     float quad1[] =  {
5861         -1.0,   -1.0,   0.1,
5862          0.0,   -1.0,   0.1,
5863         -1.0,    0.0,   0.1,
5864          0.0,    0.0,   0.1
5865     };
5866     float quad2[] =  {
5867          0.0,   -1.0,   0.1,
5868          1.0,   -1.0,   0.1,
5869          0.0,    0.0,   0.1,
5870          1.0,    0.0,   0.1
5871     };
5872     float quad3[] =  {
5873         -1.0,    0.0,   0.1,
5874          0.0,    0.0,   0.1,
5875         -1.0,    1.0,   0.1,
5876          0.0,    1.0,   0.1
5877     };
5878     float quad4[] =  {
5879          0.0,    0.0,   0.1,
5880          1.0,    0.0,   0.1,
5881          0.0,    1.0,   0.1,
5882          1.0,    1.0,   0.1
5883     };
5884     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5885     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5886
5887     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5888     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5889
5890     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5891     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5892     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5893     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5894     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5895     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5896     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5897     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5898     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5899     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5900     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5901     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5902     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5903     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5904
5905     hr = IDirect3DDevice9_BeginScene(device);
5906     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5907     if(SUCCEEDED(hr))
5908     {
5909         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5910         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5911         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5912         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5913
5914         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5915         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5916         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5917         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5918
5919         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5920         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5921         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5922         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5923
5924         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5925         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5926
5927         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5928         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5929         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5930         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5931
5932         hr = IDirect3DDevice9_EndScene(device);
5933         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5934     }
5935
5936     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5937     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5938
5939     color = getPixelColor(device, 160, 360);
5940     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5941     color = getPixelColor(device, 480, 360);
5942     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5943     color = getPixelColor(device, 160, 120);
5944     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5945     color = getPixelColor(device, 480, 160);
5946     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5947
5948     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5949     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5950
5951     IDirect3DVertexShader9_Release(shader_sge_vec);
5952     IDirect3DVertexShader9_Release(shader_slt_vec);
5953     IDirect3DVertexShader9_Release(shader_sge_scalar);
5954     IDirect3DVertexShader9_Release(shader_slt_scalar);
5955 }
5956
5957 static void test_vshader_input(IDirect3DDevice9 *device)
5958 {
5959     static const DWORD swapped_shader_code_3[] =
5960     {
5961         0xfffe0300,                                         /* vs_3_0               */
5962         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5963         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5964         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5965         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5966         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5967         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5968         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5969         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5970         0x0000ffff                                          /* end                  */
5971     };
5972     static const DWORD swapped_shader_code_1[] =
5973     {
5974         0xfffe0101,                                         /* vs_1_1               */
5975         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5976         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5977         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5978         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5979         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5980         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5981         0x0000ffff                                          /* end                  */
5982     };
5983     static const DWORD swapped_shader_code_2[] =
5984     {
5985         0xfffe0200,                                         /* vs_2_0               */
5986         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5987         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5988         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5989         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5990         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5991         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5992         0x0000ffff                                          /* end                  */
5993     };
5994     static const DWORD texcoord_color_shader_code_3[] =
5995     {
5996         0xfffe0300,                                         /* vs_3_0               */
5997         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5998         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5999         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6000         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6001         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6002         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6003         0x0000ffff                                          /* end                  */
6004     };
6005     static const DWORD texcoord_color_shader_code_2[] =
6006     {
6007         0xfffe0200,                                         /* vs_2_0               */
6008         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6009         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6010         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6011         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6012         0x0000ffff                                          /* end                  */
6013     };
6014     static const DWORD texcoord_color_shader_code_1[] =
6015     {
6016         0xfffe0101,                                         /* vs_1_1               */
6017         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6018         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6019         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6020         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6021         0x0000ffff                                          /* end                  */
6022     };
6023     static const DWORD color_color_shader_code_3[] =
6024     {
6025         0xfffe0300,                                         /* vs_3_0               */
6026         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6027         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6028         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6029         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6030         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6031         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6032         0x0000ffff                                          /* end                  */
6033     };
6034     static const DWORD color_color_shader_code_2[] =
6035     {
6036         0xfffe0200,                                         /* vs_2_0               */
6037         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6038         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6039         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6040         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6041         0x0000ffff                                          /* end                  */
6042     };
6043     static const DWORD color_color_shader_code_1[] =
6044     {
6045         0xfffe0101,                                         /* vs_1_1               */
6046         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6047         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6048         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6049         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1      */
6050         0x0000ffff                                          /* end                  */
6051     };
6052     static const DWORD ps3_code[] =
6053     {
6054         0xffff0300,                                         /* ps_3_0               */
6055         0x0200001f, 0x8000000a, 0x900f0000,                 /* dcl_color0 v0        */
6056         0x02000001, 0x800f0800, 0x90e40000,                 /* mov oC0, v0          */
6057         0x0000ffff                                          /* end                  */
6058     };
6059     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6060     IDirect3DPixelShader9 *ps;
6061     HRESULT hr;
6062     DWORD color;
6063     float quad1[] =  {
6064         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6065          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6066         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6067          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6068     };
6069     float quad2[] =  {
6070          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6071          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6072          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6073          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6074     };
6075     float quad3[] =  {
6076         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6077          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6078         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6079          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6080     };
6081     float quad4[] =  {
6082          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6083          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6084          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6085          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6086     };
6087     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6088         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6089         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6090         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6091         D3DDECL_END()
6092     };
6093     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6094         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6095         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6096         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6097         D3DDECL_END()
6098     };
6099     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6100         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6101         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6102         D3DDECL_END()
6103     };
6104     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6105         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6106         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6107         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6108         D3DDECL_END()
6109     };
6110     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6111         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6112         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6113         D3DDECL_END()
6114     };
6115     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6116         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6117         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6118         D3DDECL_END()
6119     };
6120     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6121         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6122         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6123         D3DDECL_END()
6124     };
6125     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6126         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6127         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6128         D3DDECL_END()
6129     };
6130     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6131     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6132     unsigned int i;
6133     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6134     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6135
6136     struct vertex quad1_color[] =  {
6137        {-1.0,   -1.0,   0.1,    0x00ff8040},
6138        { 0.0,   -1.0,   0.1,    0x00ff8040},
6139        {-1.0,    0.0,   0.1,    0x00ff8040},
6140        { 0.0,    0.0,   0.1,    0x00ff8040}
6141     };
6142     struct vertex quad2_color[] =  {
6143        { 0.0,   -1.0,   0.1,    0x00ff8040},
6144        { 1.0,   -1.0,   0.1,    0x00ff8040},
6145        { 0.0,    0.0,   0.1,    0x00ff8040},
6146        { 1.0,    0.0,   0.1,    0x00ff8040}
6147     };
6148     struct vertex quad3_color[] =  {
6149        {-1.0,    0.0,   0.1,    0x00ff8040},
6150        { 0.0,    0.0,   0.1,    0x00ff8040},
6151        {-1.0,    1.0,   0.1,    0x00ff8040},
6152        { 0.0,    1.0,   0.1,    0x00ff8040}
6153     };
6154     float quad4_color[] =  {
6155          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6156          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6157          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6158          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6159     };
6160
6161     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6162     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6163     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6164     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6165     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6166     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6167     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6168     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6169
6170     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6171     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6172     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6173     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6174     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6175     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6176     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6177     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6178
6179     hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
6180     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6181
6182     for(i = 1; i <= 3; i++) {
6183         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6184         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6185         if(i == 3) {
6186             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6187             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6188             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6189             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6190         } else if(i == 2){
6191             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6192             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6193         } else if(i == 1) {
6194             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6195             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6196         }
6197
6198         hr = IDirect3DDevice9_BeginScene(device);
6199         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6200         if(SUCCEEDED(hr))
6201         {
6202             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6203             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6204
6205             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6206             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6207             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6208             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6209
6210             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6211             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6212             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6213             if(i == 3 || i == 2) {
6214                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6215             } else if(i == 1) {
6216                 /* Succeeds or fails, depending on SW or HW vertex processing */
6217                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6218             }
6219
6220             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6221             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6222             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6223             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6224
6225             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6226             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6227             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6228             if(i == 3 || i == 2) {
6229                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6230             } else if(i == 1) {
6231                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6232             }
6233
6234             hr = IDirect3DDevice9_EndScene(device);
6235             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6236         }
6237
6238         if(i == 3 || i == 2) {
6239             color = getPixelColor(device, 160, 360);
6240             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6241                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6242
6243             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6244             color = getPixelColor(device, 480, 360);
6245             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6246                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6247             color = getPixelColor(device, 160, 120);
6248             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6249             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6250                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6251
6252             color = getPixelColor(device, 480, 160);
6253             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6254         } else if(i == 1) {
6255             color = getPixelColor(device, 160, 360);
6256             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6257                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6258             color = getPixelColor(device, 480, 360);
6259             /* Accept the clear color as well in this case, since SW VP returns an error */
6260             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6261             color = getPixelColor(device, 160, 120);
6262             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6263                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6264             color = getPixelColor(device, 480, 160);
6265             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6266         }
6267
6268         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6269         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6270
6271         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6272         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6273
6274         /* Now find out if the whole streams are re-read, or just the last active value for the
6275          * vertices is used.
6276          */
6277         hr = IDirect3DDevice9_BeginScene(device);
6278         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6279         if(SUCCEEDED(hr))
6280         {
6281             float quad1_modified[] =  {
6282                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6283                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6284                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6285                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6286             };
6287             float quad2_modified[] =  {
6288                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6289                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6290                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6291                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6292             };
6293
6294             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6295             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6296
6297             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6298             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6299             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6300             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6301
6302             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6303             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6304             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6305             if(i == 3 || i == 2) {
6306                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6307             } else if(i == 1) {
6308                 /* Succeeds or fails, depending on SW or HW vertex processing */
6309                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6310             }
6311
6312             hr = IDirect3DDevice9_EndScene(device);
6313             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6314         }
6315
6316         color = getPixelColor(device, 480, 350);
6317         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6318          * as well.
6319          *
6320          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6321          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6322          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6323          * refrast's result.
6324          *
6325          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6326          */
6327         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6328            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6329
6330         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6331         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6332
6333         IDirect3DDevice9_SetVertexShader(device, NULL);
6334         IDirect3DDevice9_SetPixelShader(device, NULL);
6335         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6336
6337         IDirect3DVertexShader9_Release(swapped_shader);
6338     }
6339
6340     for(i = 1; i <= 3; i++) {
6341         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6342         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6343         if(i == 3) {
6344             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6345             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6346             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6347             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6348             hr = IDirect3DDevice9_SetPixelShader(device, ps);
6349             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6350         } else if(i == 2){
6351             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6352             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6353             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6354             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6355         } else if(i == 1) {
6356             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6357             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6358             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6359             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6360         }
6361
6362         hr = IDirect3DDevice9_BeginScene(device);
6363         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6364         if(SUCCEEDED(hr))
6365         {
6366             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6367             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6368             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6369             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6370             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6371             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6372
6373             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6374             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6375
6376             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6377             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6378             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6379             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6380             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6381             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6382
6383             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6384             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6385             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6386             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6387             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6388             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6389
6390             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6391             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6392             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6393             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6394
6395             hr = IDirect3DDevice9_EndScene(device);
6396             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6397         }
6398         IDirect3DDevice9_SetVertexShader(device, NULL);
6399         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6400         IDirect3DDevice9_SetPixelShader(device, NULL);
6401
6402         color = getPixelColor(device, 160, 360);
6403         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6404            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6405         color = getPixelColor(device, 480, 360);
6406         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6407            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6408         color = getPixelColor(device, 160, 120);
6409         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6410            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6411         color = getPixelColor(device, 480, 160);
6412         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6413            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6414
6415         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6416         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6417
6418         IDirect3DVertexShader9_Release(texcoord_color_shader);
6419         IDirect3DVertexShader9_Release(color_color_shader);
6420     }
6421
6422     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6423     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6424     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6425     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6426
6427     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6428     IDirect3DVertexDeclaration9_Release(decl_color_color);
6429     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6430     IDirect3DVertexDeclaration9_Release(decl_color_float);
6431
6432     IDirect3DPixelShader9_Release(ps);
6433 }
6434
6435 static void srgbtexture_test(IDirect3DDevice9 *device)
6436 {
6437     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6438      * texture stage state to render a quad using that texture.  The resulting
6439      * color components should be 0x36 (~ 0.21), per this formula:
6440      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6441      * This is true where srgb_color > 0.04045.
6442      */
6443     IDirect3D9 *d3d = NULL;
6444     HRESULT hr;
6445     LPDIRECT3DTEXTURE9 texture = NULL;
6446     LPDIRECT3DSURFACE9 surface = NULL;
6447     D3DLOCKED_RECT lr;
6448     DWORD color;
6449     float quad[] = {
6450         -1.0,       1.0,       0.0,     0.0,    0.0,
6451          1.0,       1.0,       0.0,     1.0,    0.0,
6452         -1.0,      -1.0,       0.0,     0.0,    1.0,
6453          1.0,      -1.0,       0.0,     1.0,    1.0,
6454     };
6455
6456
6457     memset(&lr, 0, sizeof(lr));
6458     IDirect3DDevice9_GetDirect3D(device, &d3d);
6459     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6460                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6461                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6462         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6463         goto out;
6464     }
6465
6466     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6467                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6468                                         &texture, NULL);
6469     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6470     if(!texture) {
6471         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6472         goto out;
6473     }
6474     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6475     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6476
6477     fill_surface(surface, 0xff7f7f7f);
6478     IDirect3DSurface9_Release(surface);
6479
6480     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6481     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6482     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6483     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6484
6485     hr = IDirect3DDevice9_BeginScene(device);
6486     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6487     if(SUCCEEDED(hr))
6488     {
6489         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6490         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6491
6492         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6493         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6494
6495
6496         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6497         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6498
6499         hr = IDirect3DDevice9_EndScene(device);
6500         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6501     }
6502
6503     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6504     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6505     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6506     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6507
6508     color = getPixelColor(device, 320, 240);
6509     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6510
6511     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6512     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6513
6514 out:
6515     if(texture) IDirect3DTexture9_Release(texture);
6516     IDirect3D9_Release(d3d);
6517 }
6518
6519 static void shademode_test(IDirect3DDevice9 *device)
6520 {
6521     /* Render a quad and try all of the different fixed function shading models. */
6522     HRESULT hr;
6523     DWORD color0, color1;
6524     DWORD color0_gouraud = 0, color1_gouraud = 0;
6525     DWORD shademode = D3DSHADE_FLAT;
6526     DWORD primtype = D3DPT_TRIANGLESTRIP;
6527     LPVOID data = NULL;
6528     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6529     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6530     UINT i, j;
6531     struct vertex quad_strip[] =
6532     {
6533         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6534         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6535         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6536         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6537     };
6538     struct vertex quad_list[] =
6539     {
6540         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6541         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6542         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6543
6544         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6545         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6546         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6547     };
6548
6549     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6550                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6551     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6552     if (FAILED(hr)) goto bail;
6553
6554     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6555                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6556     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6557     if (FAILED(hr)) goto bail;
6558
6559     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6560     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6561
6562     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6563     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6564
6565     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6566     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6567     memcpy(data, quad_strip, sizeof(quad_strip));
6568     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6569     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6570
6571     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6572     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6573     memcpy(data, quad_list, sizeof(quad_list));
6574     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6575     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6576
6577     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6578      * the color fixups we have to do for FLAT shading will be dependent on that. */
6579     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6580     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6581
6582     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6583     for (j=0; j<2; j++) {
6584
6585         /* Inner loop just changes the D3DRS_SHADEMODE */
6586         for (i=0; i<3; i++) {
6587             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6588             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6589
6590             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6591             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6592
6593             hr = IDirect3DDevice9_BeginScene(device);
6594             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6595             if(SUCCEEDED(hr))
6596             {
6597                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6598                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6599
6600                 hr = IDirect3DDevice9_EndScene(device);
6601                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6602             }
6603
6604             /* Sample two spots from the output */
6605             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6606             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6607             switch(shademode) {
6608                 case D3DSHADE_FLAT:
6609                     /* Should take the color of the first vertex of each triangle */
6610                     if (0)
6611                     {
6612                         /* This test depends on EXT_provoking_vertex being
6613                          * available. This extension is currently (20090810)
6614                          * not common enough to let the test fail if it isn't
6615                          * present. */
6616                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6617                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6618                     }
6619                     shademode = D3DSHADE_GOURAUD;
6620                     break;
6621                 case D3DSHADE_GOURAUD:
6622                     /* Should be an interpolated blend */
6623
6624                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6625                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6626                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6627                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6628
6629                     color0_gouraud = color0;
6630                     color1_gouraud = color1;
6631
6632                     shademode = D3DSHADE_PHONG;
6633                     break;
6634                 case D3DSHADE_PHONG:
6635                     /* Should be the same as GOURAUD, since no hardware implements this */
6636                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6637                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6638                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6639                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6640
6641                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6642                             color0_gouraud, color0);
6643                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6644                             color1_gouraud, color1);
6645                     break;
6646             }
6647         }
6648
6649         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6650         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6651
6652         /* Now, do it all over again with a TRIANGLELIST */
6653         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6654         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6655         primtype = D3DPT_TRIANGLELIST;
6656         shademode = D3DSHADE_FLAT;
6657     }
6658
6659 bail:
6660     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6661     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6662     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6663     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6664
6665     if (vb_strip)
6666         IDirect3DVertexBuffer9_Release(vb_strip);
6667     if (vb_list)
6668         IDirect3DVertexBuffer9_Release(vb_list);
6669 }
6670
6671 static void alpha_test(IDirect3DDevice9 *device)
6672 {
6673     HRESULT hr;
6674     IDirect3DTexture9 *offscreenTexture;
6675     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6676     DWORD color;
6677
6678     struct vertex quad1[] =
6679     {
6680         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6681         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6682         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6683         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6684     };
6685     struct vertex quad2[] =
6686     {
6687         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6688         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6689         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6690         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6691     };
6692     static const float composite_quad[][5] = {
6693         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6694         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6695         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6696         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6697     };
6698
6699     /* Clear the render target with alpha = 0.5 */
6700     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6701     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6702
6703     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6704     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6705
6706     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6707     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6708     if(!backbuffer) {
6709         goto out;
6710     }
6711
6712     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6713     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6714     if(!offscreen) {
6715         goto out;
6716     }
6717
6718     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6719     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6720
6721     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6722     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6723     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6724     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6725     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6726     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6727     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6728     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6729     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6730     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6731
6732     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6733     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6734     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6735
6736         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6737         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6738         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6739         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6740         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6741         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6742         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6743
6744         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6745         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6746         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6747         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6748         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6749         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6750
6751         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6752          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6753          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6754         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6755         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6756         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6757         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6758
6759         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6760         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6761         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6762         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6763         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6764         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6765
6766         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6767         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6768         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6769         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6770         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6771         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6772
6773         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6774         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6775
6776         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6777          * Disable alpha blending for the final composition
6778          */
6779         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6780         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6781         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6782         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6783
6784         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6785         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6786         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6787         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6788         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6789         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6790
6791         hr = IDirect3DDevice9_EndScene(device);
6792         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6793     }
6794
6795     color = getPixelColor(device, 160, 360);
6796     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6797        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6798
6799     color = getPixelColor(device, 160, 120);
6800     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6801        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6802
6803     color = getPixelColor(device, 480, 360);
6804     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6805        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6806
6807     color = getPixelColor(device, 480, 120);
6808     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6809        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6810
6811     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6812
6813     out:
6814     /* restore things */
6815     if(backbuffer) {
6816         IDirect3DSurface9_Release(backbuffer);
6817     }
6818     if(offscreenTexture) {
6819         IDirect3DTexture9_Release(offscreenTexture);
6820     }
6821     if(offscreen) {
6822         IDirect3DSurface9_Release(offscreen);
6823     }
6824 }
6825
6826 struct vertex_shortcolor {
6827     float x, y, z;
6828     unsigned short r, g, b, a;
6829 };
6830 struct vertex_floatcolor {
6831     float x, y, z;
6832     float r, g, b, a;
6833 };
6834
6835 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6836 {
6837     HRESULT hr;
6838     BOOL s_ok, ub_ok, f_ok;
6839     DWORD color, size, i;
6840     void *data;
6841     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6842         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6843         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6844         D3DDECL_END()
6845     };
6846     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6847         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6848         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6849         D3DDECL_END()
6850     };
6851     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6852         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6853         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6854         D3DDECL_END()
6855     };
6856     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6857         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6858         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6859         D3DDECL_END()
6860     };
6861     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6862         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6863         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6864         D3DDECL_END()
6865     };
6866     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6867         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6868         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6869         D3DDECL_END()
6870     };
6871     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6872         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6873         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6874         D3DDECL_END()
6875     };
6876     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6877     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6878     IDirect3DVertexBuffer9 *vb, *vb2;
6879     struct vertex quad1[] =                             /* D3DCOLOR */
6880     {
6881         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6882         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6883         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6884         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6885     };
6886     struct vertex quad2[] =                             /* UBYTE4N */
6887     {
6888         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6889         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6890         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6891         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6892     };
6893     struct vertex_shortcolor quad3[] =                  /* short */
6894     {
6895         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6896         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6897         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6898         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6899     };
6900     struct vertex_floatcolor quad4[] =
6901     {
6902         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6903         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6904         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6905         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6906     };
6907     DWORD colors[] = {
6908         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6909         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6910         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6911         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6912         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6913         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6914         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6915         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6916         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6917         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6918         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6919         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6920         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6921         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6922         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6923         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6924     };
6925     float quads[] = {
6926         -1.0,   -1.0,     0.1,
6927         -1.0,    0.0,     0.1,
6928          0.0,   -1.0,     0.1,
6929          0.0,    0.0,     0.1,
6930
6931          0.0,   -1.0,     0.1,
6932          0.0,    0.0,     0.1,
6933          1.0,   -1.0,     0.1,
6934          1.0,    0.0,     0.1,
6935
6936          0.0,    0.0,     0.1,
6937          0.0,    1.0,     0.1,
6938          1.0,    0.0,     0.1,
6939          1.0,    1.0,     0.1,
6940
6941         -1.0,    0.0,     0.1,
6942         -1.0,    1.0,     0.1,
6943          0.0,    0.0,     0.1,
6944          0.0,    1.0,     0.1
6945     };
6946     struct tvertex quad_transformed[] = {
6947        {  90,    110,     0.1,      2.0,        0x00ffff00},
6948        { 570,    110,     0.1,      2.0,        0x00ffff00},
6949        {  90,    300,     0.1,      2.0,        0x00ffff00},
6950        { 570,    300,     0.1,      2.0,        0x00ffff00}
6951     };
6952     D3DCAPS9 caps;
6953
6954     memset(&caps, 0, sizeof(caps));
6955     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6956     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6957
6958     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6959     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6960
6961     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6962     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6963     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6964     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6965     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6966     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6967     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6968         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6969         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6970         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6971         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6972     } else {
6973         trace("D3DDTCAPS_UBYTE4N not supported\n");
6974         dcl_ubyte_2 = NULL;
6975         dcl_ubyte = NULL;
6976     }
6977     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6978     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6979     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6980     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6981
6982     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6983     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6984                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
6985     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6986
6987     hr = IDirect3DDevice9_BeginScene(device);
6988     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6989     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6990     if(SUCCEEDED(hr)) {
6991         if(dcl_color) {
6992             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6993             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6994             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6995             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6996         }
6997
6998         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
6999          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7000          * using software vertex processing. Doh!
7001          */
7002         if(dcl_ubyte) {
7003             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7004             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7005             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7006             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7007             ub_ok = SUCCEEDED(hr);
7008         }
7009
7010         if(dcl_short) {
7011             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7012             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7013             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7014             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7015             s_ok = SUCCEEDED(hr);
7016         }
7017
7018         if(dcl_float) {
7019             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7020             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7021             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7022             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7023             f_ok = SUCCEEDED(hr);
7024         }
7025
7026         hr = IDirect3DDevice9_EndScene(device);
7027         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7028     }
7029
7030     if(dcl_short) {
7031         color = getPixelColor(device, 480, 360);
7032         ok(color == 0x000000ff || !s_ok,
7033            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7034     }
7035     if(dcl_ubyte) {
7036         color = getPixelColor(device, 160, 120);
7037         ok(color == 0x0000ffff || !ub_ok,
7038            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7039     }
7040     if(dcl_color) {
7041         color = getPixelColor(device, 160, 360);
7042         ok(color == 0x00ffff00,
7043            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7044     }
7045     if(dcl_float) {
7046         color = getPixelColor(device, 480, 120);
7047         ok(color == 0x00ff0000 || !f_ok,
7048            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7049     }
7050     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7051
7052     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7053      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7054      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7055      * whether the immediate mode code works
7056      */
7057     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7058     hr = IDirect3DDevice9_BeginScene(device);
7059     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7060     if(SUCCEEDED(hr)) {
7061         if(dcl_color) {
7062             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7063             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7064             memcpy(data, quad1, sizeof(quad1));
7065             hr = IDirect3DVertexBuffer9_Unlock(vb);
7066             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7067             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7068             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7069             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7070             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7071             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7072             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7073         }
7074
7075         if(dcl_ubyte) {
7076             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7077             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7078             memcpy(data, quad2, sizeof(quad2));
7079             hr = IDirect3DVertexBuffer9_Unlock(vb);
7080             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7081             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7082             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7083             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7084             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7085             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7086             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7087                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7088             ub_ok = SUCCEEDED(hr);
7089         }
7090
7091         if(dcl_short) {
7092             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7093             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7094             memcpy(data, quad3, sizeof(quad3));
7095             hr = IDirect3DVertexBuffer9_Unlock(vb);
7096             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7097             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7098             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7099             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7100             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7101             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7102             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7103                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7104             s_ok = SUCCEEDED(hr);
7105         }
7106
7107         if(dcl_float) {
7108             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7109             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7110             memcpy(data, quad4, sizeof(quad4));
7111             hr = IDirect3DVertexBuffer9_Unlock(vb);
7112             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7113             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7114             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7115             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7116             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7117             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7118             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7119                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7120             f_ok = SUCCEEDED(hr);
7121         }
7122
7123         hr = IDirect3DDevice9_EndScene(device);
7124         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7125     }
7126
7127     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7128     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7129     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7130     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7131
7132     if(dcl_short) {
7133         color = getPixelColor(device, 480, 360);
7134         ok(color == 0x000000ff || !s_ok,
7135            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7136     }
7137     if(dcl_ubyte) {
7138         color = getPixelColor(device, 160, 120);
7139         ok(color == 0x0000ffff || !ub_ok,
7140            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7141     }
7142     if(dcl_color) {
7143         color = getPixelColor(device, 160, 360);
7144         ok(color == 0x00ffff00,
7145            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7146     }
7147     if(dcl_float) {
7148         color = getPixelColor(device, 480, 120);
7149         ok(color == 0x00ff0000 || !f_ok,
7150            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7151     }
7152     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7153
7154     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7155     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7156
7157     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7158     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7159     memcpy(data, quad_transformed, sizeof(quad_transformed));
7160     hr = IDirect3DVertexBuffer9_Unlock(vb);
7161     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7162
7163     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7164     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7165
7166     hr = IDirect3DDevice9_BeginScene(device);
7167     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7168     if(SUCCEEDED(hr)) {
7169         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7170         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7171         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7172         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7173
7174         hr = IDirect3DDevice9_EndScene(device);
7175         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7176     }
7177
7178     color = getPixelColor(device, 88, 108);
7179     ok(color == 0x000000ff,
7180        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7181     color = getPixelColor(device, 92, 108);
7182     ok(color == 0x000000ff,
7183        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7184     color = getPixelColor(device, 88, 112);
7185     ok(color == 0x000000ff,
7186        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7187     color = getPixelColor(device, 92, 112);
7188     ok(color == 0x00ffff00,
7189        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7190
7191     color = getPixelColor(device, 568, 108);
7192     ok(color == 0x000000ff,
7193        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7194     color = getPixelColor(device, 572, 108);
7195     ok(color == 0x000000ff,
7196        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7197     color = getPixelColor(device, 568, 112);
7198     ok(color == 0x00ffff00,
7199        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7200     color = getPixelColor(device, 572, 112);
7201     ok(color == 0x000000ff,
7202        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7203
7204     color = getPixelColor(device, 88, 298);
7205     ok(color == 0x000000ff,
7206        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7207     color = getPixelColor(device, 92, 298);
7208     ok(color == 0x00ffff00,
7209        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7210     color = getPixelColor(device, 88, 302);
7211     ok(color == 0x000000ff,
7212        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7213     color = getPixelColor(device, 92, 302);
7214     ok(color == 0x000000ff,
7215        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7216
7217     color = getPixelColor(device, 568, 298);
7218     ok(color == 0x00ffff00,
7219        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7220     color = getPixelColor(device, 572, 298);
7221     ok(color == 0x000000ff,
7222        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7223     color = getPixelColor(device, 568, 302);
7224     ok(color == 0x000000ff,
7225        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7226     color = getPixelColor(device, 572, 302);
7227     ok(color == 0x000000ff,
7228        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7229
7230     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7231
7232     /* This test is pointless without those two declarations: */
7233     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7234         skip("color-ubyte switching test declarations aren't supported\n");
7235         goto out;
7236     }
7237
7238     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7239     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7240     memcpy(data, quads, sizeof(quads));
7241     hr = IDirect3DVertexBuffer9_Unlock(vb);
7242     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7243     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7244                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7245     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7246     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7247     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7248     memcpy(data, colors, sizeof(colors));
7249     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7250     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7251
7252     for(i = 0; i < 2; i++) {
7253         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7254         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7255
7256         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7257         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7258         if(i == 0) {
7259             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7260         } else {
7261             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7262         }
7263         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7264
7265         hr = IDirect3DDevice9_BeginScene(device);
7266         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7267         ub_ok = FALSE;
7268         if(SUCCEEDED(hr)) {
7269             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7270             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7271             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7272             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7273                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7274             ub_ok = SUCCEEDED(hr);
7275
7276             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7277             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7278             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7279             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7280
7281             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7282             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7283             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7284             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7285                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7286             ub_ok = (SUCCEEDED(hr) && ub_ok);
7287
7288             hr = IDirect3DDevice9_EndScene(device);
7289             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7290         }
7291
7292         if(i == 0) {
7293             color = getPixelColor(device, 480, 360);
7294             ok(color == 0x00ff0000,
7295                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7296             color = getPixelColor(device, 160, 120);
7297             ok(color == 0x00ffffff,
7298                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7299             color = getPixelColor(device, 160, 360);
7300             ok(color == 0x000000ff || !ub_ok,
7301                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7302             color = getPixelColor(device, 480, 120);
7303             ok(color == 0x000000ff || !ub_ok,
7304                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7305         } else {
7306             color = getPixelColor(device, 480, 360);
7307             ok(color == 0x000000ff,
7308                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7309             color = getPixelColor(device, 160, 120);
7310             ok(color == 0x00ffffff,
7311                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7312             color = getPixelColor(device, 160, 360);
7313             ok(color == 0x00ff0000 || !ub_ok,
7314                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7315             color = getPixelColor(device, 480, 120);
7316             ok(color == 0x00ff0000 || !ub_ok,
7317                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7318         }
7319         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7320     }
7321
7322     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7323     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7324     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7325     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7326     IDirect3DVertexBuffer9_Release(vb2);
7327
7328     out:
7329     IDirect3DVertexBuffer9_Release(vb);
7330     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7331     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7332     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7333     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7334     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7335     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7336     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7337 }
7338
7339 struct vertex_float16color {
7340     float x, y, z;
7341     DWORD c1, c2;
7342 };
7343
7344 static void test_vshader_float16(IDirect3DDevice9 *device)
7345 {
7346     HRESULT hr;
7347     DWORD color;
7348     void *data;
7349     static const D3DVERTEXELEMENT9 decl_elements[] = {
7350         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7351         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7352         D3DDECL_END()
7353     };
7354     IDirect3DVertexDeclaration9 *vdecl = NULL;
7355     IDirect3DVertexBuffer9 *buffer = NULL;
7356     IDirect3DVertexShader9 *shader;
7357     DWORD shader_code[] = {
7358         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7359         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7360         0x90e40001, 0x0000ffff
7361     };
7362     struct vertex_float16color quad[] = {
7363         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7364         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7365         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7366         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7367
7368         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7369         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7370         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7371         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7372
7373         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7374         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7375         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7376         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7377
7378         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7379         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7380         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7381         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7382     };
7383
7384     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7385     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7386
7387     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7388     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7389     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7390     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7391     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7392     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7393
7394     hr = IDirect3DDevice9_BeginScene(device);
7395     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7396     if(SUCCEEDED(hr)) {
7397         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7398         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7399         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7400         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7401         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7402         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7403         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7404         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7405         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7406         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7407
7408         hr = IDirect3DDevice9_EndScene(device);
7409         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7410     }
7411     color = getPixelColor(device, 480, 360);
7412     ok(color == 0x00ff0000,
7413        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7414     color = getPixelColor(device, 160, 120);
7415     ok(color == 0x00000000,
7416        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7417     color = getPixelColor(device, 160, 360);
7418     ok(color == 0x0000ff00,
7419        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7420     color = getPixelColor(device, 480, 120);
7421     ok(color == 0x000000ff,
7422        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7423     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7424
7425     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7426     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7427
7428     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7429                                              D3DPOOL_MANAGED, &buffer, NULL);
7430     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7431     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7432     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7433     memcpy(data, quad, sizeof(quad));
7434     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7435     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7436     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7437     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7438
7439     hr = IDirect3DDevice9_BeginScene(device);
7440     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7441     if(SUCCEEDED(hr)) {
7442             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7443             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7444             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7445             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7446             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7447             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7448             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7449             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7450
7451             hr = IDirect3DDevice9_EndScene(device);
7452             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7453     }
7454
7455     color = getPixelColor(device, 480, 360);
7456     ok(color == 0x00ff0000,
7457        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7458     color = getPixelColor(device, 160, 120);
7459     ok(color == 0x00000000,
7460        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7461     color = getPixelColor(device, 160, 360);
7462     ok(color == 0x0000ff00,
7463        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7464     color = getPixelColor(device, 480, 120);
7465     ok(color == 0x000000ff,
7466        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7467     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7468
7469     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7470     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7471     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7472     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7473     IDirect3DDevice9_SetVertexShader(device, NULL);
7474     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7475
7476     IDirect3DVertexDeclaration9_Release(vdecl);
7477     IDirect3DVertexShader9_Release(shader);
7478     IDirect3DVertexBuffer9_Release(buffer);
7479 }
7480
7481 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7482 {
7483     D3DCAPS9 caps;
7484     IDirect3DTexture9 *texture;
7485     HRESULT hr;
7486     D3DLOCKED_RECT rect;
7487     unsigned int x, y;
7488     DWORD *dst, color;
7489     const float quad[] = {
7490         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7491          1.0,   -1.0,   0.1,    1.2,   -0.2,
7492         -1.0,    1.0,   0.1,   -0.2,    1.2,
7493          1.0,    1.0,   0.1,    1.2,    1.2
7494     };
7495     memset(&caps, 0, sizeof(caps));
7496
7497     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7498     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7499     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7500         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7501         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7502            "Card has conditional NP2 support without power of two restriction set\n");
7503         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7504         return;
7505     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7506         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7507         return;
7508     }
7509
7510     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7511     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7512
7513     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7514     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7515
7516     memset(&rect, 0, sizeof(rect));
7517     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7518     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7519     for(y = 0; y < 10; y++) {
7520         for(x = 0; x < 10; x++) {
7521             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7522             if(x == 0 || x == 9 || y == 0 || y == 9) {
7523                 *dst = 0x00ff0000;
7524             } else {
7525                 *dst = 0x000000ff;
7526             }
7527         }
7528     }
7529     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7530     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7531
7532     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7533     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7534     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7535     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7536     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7537     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7538     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7539     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7540
7541     hr = IDirect3DDevice9_BeginScene(device);
7542     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7543     if(SUCCEEDED(hr)) {
7544         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7545         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7546
7547         hr = IDirect3DDevice9_EndScene(device);
7548         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7549     }
7550
7551     color = getPixelColor(device,    1,  1);
7552     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7553     color = getPixelColor(device, 639, 479);
7554     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7555
7556     color = getPixelColor(device, 135, 101);
7557     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7558     color = getPixelColor(device, 140, 101);
7559     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7560     color = getPixelColor(device, 135, 105);
7561     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7562     color = getPixelColor(device, 140, 105);
7563     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7564
7565     color = getPixelColor(device, 135, 376);
7566     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7567     color = getPixelColor(device, 140, 376);
7568     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7569     color = getPixelColor(device, 135, 379);
7570     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7571     color = getPixelColor(device, 140, 379);
7572     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7573
7574     color = getPixelColor(device, 500, 101);
7575     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7576     color = getPixelColor(device, 504, 101);
7577     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7578     color = getPixelColor(device, 500, 105);
7579     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7580     color = getPixelColor(device, 504, 105);
7581     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7582
7583     color = getPixelColor(device, 500, 376);
7584     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7585     color = getPixelColor(device, 504, 376);
7586     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7587     color = getPixelColor(device, 500, 380);
7588     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7589     color = getPixelColor(device, 504, 380);
7590     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7591
7592     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7593
7594     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7595     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7596     IDirect3DTexture9_Release(texture);
7597 }
7598
7599 static void vFace_register_test(IDirect3DDevice9 *device)
7600 {
7601     HRESULT hr;
7602     DWORD color;
7603     const DWORD shader_code[] = {
7604         0xffff0300,                                                             /* ps_3_0                     */
7605         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7606         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7607         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7608         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7609         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7610         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7611         0x0000ffff                                                              /* END                        */
7612     };
7613     const DWORD vshader_code[] = {
7614         0xfffe0300,                                                             /* vs_3_0               */
7615         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
7616         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
7617         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
7618         0x0000ffff                                                              /* end                  */
7619     };
7620     IDirect3DPixelShader9 *shader;
7621     IDirect3DVertexShader9 *vshader;
7622     IDirect3DTexture9 *texture;
7623     IDirect3DSurface9 *surface, *backbuffer;
7624     const float quad[] = {
7625         -1.0,   -1.0,   0.1,
7626          1.0,   -1.0,   0.1,
7627         -1.0,    0.0,   0.1,
7628
7629          1.0,   -1.0,   0.1,
7630          1.0,    0.0,   0.1,
7631         -1.0,    0.0,   0.1,
7632
7633         -1.0,    0.0,   0.1,
7634         -1.0,    1.0,   0.1,
7635          1.0,    0.0,   0.1,
7636
7637          1.0,    0.0,   0.1,
7638         -1.0,    1.0,   0.1,
7639          1.0,    1.0,   0.1,
7640     };
7641     const float blit[] = {
7642          0.0,   -1.0,   0.1,    0.0,    0.0,
7643          1.0,   -1.0,   0.1,    1.0,    0.0,
7644          0.0,    1.0,   0.1,    0.0,    1.0,
7645          1.0,    1.0,   0.1,    1.0,    1.0,
7646     };
7647
7648     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7649     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7650     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7651     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7652     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7653     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7654     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7655     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7656     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7657     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7658     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7659     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7660     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7661     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7662     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7663     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7664
7665     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7666     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7667
7668     hr = IDirect3DDevice9_BeginScene(device);
7669     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7670     if(SUCCEEDED(hr)) {
7671         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7672         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7673         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7674         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7675         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7676         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7677         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7678         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7679         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7680         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7681         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7682
7683         /* Blit the texture onto the back buffer to make it visible */
7684         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7685         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
7686         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7687         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7688         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7689         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7690         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7691         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7692         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7693         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7694         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7695         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7696
7697         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7698         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7699
7700         hr = IDirect3DDevice9_EndScene(device);
7701         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7702     }
7703
7704     color = getPixelColor(device, 160, 360);
7705     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7706     color = getPixelColor(device, 160, 120);
7707     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7708     color = getPixelColor(device, 480, 360);
7709     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7710     color = getPixelColor(device, 480, 120);
7711     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7712     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7713
7714     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7715     IDirect3DDevice9_SetTexture(device, 0, NULL);
7716     IDirect3DPixelShader9_Release(shader);
7717     IDirect3DVertexShader9_Release(vshader);
7718     IDirect3DSurface9_Release(surface);
7719     IDirect3DSurface9_Release(backbuffer);
7720     IDirect3DTexture9_Release(texture);
7721 }
7722
7723 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7724 {
7725     HRESULT hr;
7726     DWORD color;
7727     int i;
7728     D3DCAPS9 caps;
7729     BOOL L6V5U5_supported = FALSE;
7730     IDirect3DTexture9 *tex1, *tex2;
7731     D3DLOCKED_RECT locked_rect;
7732
7733     static const float quad[][7] = {
7734         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7735         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7736         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7737         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7738     };
7739
7740     static const D3DVERTEXELEMENT9 decl_elements[] = {
7741         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7742         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7743         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7744         D3DDECL_END()
7745     };
7746
7747     /* use asymmetric matrix to test loading */
7748     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7749     float scale, offset;
7750
7751     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7752     IDirect3DTexture9           *texture            = NULL;
7753
7754     memset(&caps, 0, sizeof(caps));
7755     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7756     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7757     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7758         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7759         return;
7760     } else {
7761         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7762          * They report that it is not supported, but after that bump mapping works properly. So just test
7763          * if the format is generally supported, and check the BUMPENVMAP flag
7764          */
7765         IDirect3D9 *d3d9;
7766
7767         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7768         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7769                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7770         L6V5U5_supported = SUCCEEDED(hr);
7771         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7772                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7773         IDirect3D9_Release(d3d9);
7774         if(FAILED(hr)) {
7775             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7776             return;
7777         }
7778     }
7779
7780     /* Generate the textures */
7781     generate_bumpmap_textures(device);
7782
7783     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7784     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7785     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7786     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7787     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7788     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7789     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7790     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7791
7792     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7793     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7794     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7795     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7796     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7797     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7798
7799     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7800     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7801     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7802     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7803     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7804     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7805
7806     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7807     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7808
7809     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7810     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7811
7812     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7813     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7814
7815
7816     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7817     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7818     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7819     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7820
7821     hr = IDirect3DDevice9_BeginScene(device);
7822     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7823
7824     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7825     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7826
7827     hr = IDirect3DDevice9_EndScene(device);
7828     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7829
7830     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7831      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7832      * But since testing the color match is not the purpose of the test don't be too picky
7833      */
7834     color = getPixelColor(device, 320-32, 240);
7835     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7836     color = getPixelColor(device, 320+32, 240);
7837     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7838     color = getPixelColor(device, 320, 240-32);
7839     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7840     color = getPixelColor(device, 320, 240+32);
7841     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7842     color = getPixelColor(device, 320, 240);
7843     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7844     color = getPixelColor(device, 320+32, 240+32);
7845     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7846     color = getPixelColor(device, 320-32, 240+32);
7847     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7848     color = getPixelColor(device, 320+32, 240-32);
7849     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7850     color = getPixelColor(device, 320-32, 240-32);
7851     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7852     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7853     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7854
7855     for(i = 0; i < 2; i++) {
7856         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7857         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7858         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7859         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7860         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7861         IDirect3DTexture9_Release(texture); /* To destroy it */
7862     }
7863
7864     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7865         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7866         goto cleanup;
7867     }
7868     if(L6V5U5_supported == FALSE) {
7869         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7870         goto cleanup;
7871     }
7872
7873     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7874     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7875     /* This test only tests the luminance part. The bumpmapping part was already tested above and
7876      * would only make this test more complicated
7877      */
7878     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7879     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7880     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7881     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7882
7883     memset(&locked_rect, 0, sizeof(locked_rect));
7884     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7885     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7886     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7887     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7888     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7889
7890     memset(&locked_rect, 0, sizeof(locked_rect));
7891     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7892     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7893     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7894     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7895     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7896
7897     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7898     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7899     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7900     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7901
7902     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7903     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7904     scale = 2.0;
7905     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7906     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7907     offset = 0.1;
7908     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7909     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7910
7911     hr = IDirect3DDevice9_BeginScene(device);
7912     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7913     if(SUCCEEDED(hr)) {
7914         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7915         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7916         hr = IDirect3DDevice9_EndScene(device);
7917         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7918     }
7919
7920     color = getPixelColor(device, 320, 240);
7921     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
7922      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
7923      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7924      */
7925     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7926     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7927     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7928
7929     /* Check a result scale factor > 1.0 */
7930     scale = 10;
7931     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7932     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7933     offset = 10;
7934     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7935     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7936
7937     hr = IDirect3DDevice9_BeginScene(device);
7938     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7939     if(SUCCEEDED(hr)) {
7940         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7941         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7942         hr = IDirect3DDevice9_EndScene(device);
7943         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7944     }
7945     color = getPixelColor(device, 320, 240);
7946     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7947     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7948     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7949
7950     /* Check clamping in the scale factor calculation */
7951     scale = 1000;
7952     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7953     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7954     offset = -1;
7955     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7956     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7957
7958     hr = IDirect3DDevice9_BeginScene(device);
7959     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7960     if(SUCCEEDED(hr)) {
7961         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7962         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7963         hr = IDirect3DDevice9_EndScene(device);
7964         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7965     }
7966     color = getPixelColor(device, 320, 240);
7967     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7968     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7969     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7970
7971     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7972     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7973     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
7974     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7975
7976     IDirect3DTexture9_Release(tex1);
7977     IDirect3DTexture9_Release(tex2);
7978
7979 cleanup:
7980     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7981     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7982     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7983     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7984
7985     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7986     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7987     IDirect3DVertexDeclaration9_Release(vertex_declaration);
7988 }
7989
7990 static void stencil_cull_test(IDirect3DDevice9 *device) {
7991     HRESULT hr;
7992     IDirect3DSurface9 *depthstencil = NULL;
7993     D3DSURFACE_DESC desc;
7994     float quad1[] = {
7995         -1.0,   -1.0,   0.1,
7996          0.0,   -1.0,   0.1,
7997         -1.0,    0.0,   0.1,
7998          0.0,    0.0,   0.1,
7999     };
8000     float quad2[] = {
8001          0.0,   -1.0,   0.1,
8002          1.0,   -1.0,   0.1,
8003          0.0,    0.0,   0.1,
8004          1.0,    0.0,   0.1,
8005     };
8006     float quad3[] = {
8007         0.0,    0.0,   0.1,
8008         1.0,    0.0,   0.1,
8009         0.0,    1.0,   0.1,
8010         1.0,    1.0,   0.1,
8011     };
8012     float quad4[] = {
8013         -1.0,    0.0,   0.1,
8014          0.0,    0.0,   0.1,
8015         -1.0,    1.0,   0.1,
8016          0.0,    1.0,   0.1,
8017     };
8018     struct vertex painter[] = {
8019        {-1.0,   -1.0,   0.0,    0x00000000},
8020        { 1.0,   -1.0,   0.0,    0x00000000},
8021        {-1.0,    1.0,   0.0,    0x00000000},
8022        { 1.0,    1.0,   0.0,    0x00000000},
8023     };
8024     WORD indices_cw[]  = {0, 1, 3};
8025     WORD indices_ccw[] = {0, 2, 3};
8026     unsigned int i;
8027     DWORD color;
8028
8029     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8030     if(depthstencil == NULL) {
8031         skip("No depth stencil buffer\n");
8032         return;
8033     }
8034     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8035     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8036     IDirect3DSurface9_Release(depthstencil);
8037     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8038         skip("No 4 or 8 bit stencil surface\n");
8039         return;
8040     }
8041
8042     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8043     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8044     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8045
8046     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8047     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8048     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8049     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8050     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8051     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8052     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8053     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8054
8055     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8056     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8057     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8058     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8059     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8060     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8061
8062     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8063     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8064     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8065     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8066
8067     /* First pass: Fill the stencil buffer with some values... */
8068     hr = IDirect3DDevice9_BeginScene(device);
8069     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8070     if(SUCCEEDED(hr))
8071     {
8072         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8073         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8074         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8075                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8076         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8077         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8078                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8079         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8080
8081         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8082         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8083         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8084         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8085         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8086                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8087         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8088         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8089                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8090         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8091
8092         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8093         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8094         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8095                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8096         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8097         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8098                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8099         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8100
8101         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8102         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8103         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8104                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8105         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8106         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8107                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8108         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8109
8110         hr = IDirect3DDevice9_EndScene(device);
8111         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8112     }
8113
8114     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8115     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8116     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8117     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8118     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8119     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8120     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8121     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8122     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8123     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8124     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8125     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8126     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8127
8128     /* 2nd pass: Make the stencil values visible */
8129     hr = IDirect3DDevice9_BeginScene(device);
8130     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8131     if(SUCCEEDED(hr))
8132     {
8133         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8134         for(i = 0; i < 16; i++) {
8135             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8136             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8137
8138             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8139             painter[1].diffuse = (i * 16);
8140             painter[2].diffuse = (i * 16);
8141             painter[3].diffuse = (i * 16);
8142             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8143             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8144         }
8145         hr = IDirect3DDevice9_EndScene(device);
8146         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8147     }
8148
8149     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8150     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8151
8152     color = getPixelColor(device, 160, 420);
8153     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8154     color = getPixelColor(device, 160, 300);
8155     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8156
8157     color = getPixelColor(device, 480, 420);
8158     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8159     color = getPixelColor(device, 480, 300);
8160     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8161
8162     color = getPixelColor(device, 160, 180);
8163     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8164     color = getPixelColor(device, 160, 60);
8165     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8166
8167     color = getPixelColor(device, 480, 180);
8168     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8169     color = getPixelColor(device, 480, 60);
8170     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8171
8172     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8173     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8174 }
8175
8176 static void vpos_register_test(IDirect3DDevice9 *device)
8177 {
8178     HRESULT hr;
8179     DWORD color;
8180     const DWORD shader_code[] = {
8181     0xffff0300,                                                             /* ps_3_0                     */
8182     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8183     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8184     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8185     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8186     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8187     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8188     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8189     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8190     0x0000ffff                                                              /* end                        */
8191     };
8192     const DWORD shader_frac_code[] = {
8193     0xffff0300,                                                             /* ps_3_0                     */
8194     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8195     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8196     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8197     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8198     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8199     0x0000ffff                                                              /* end                        */
8200     };
8201     const DWORD vshader_code[] = {
8202         0xfffe0300,                                                             /* vs_3_0               */
8203         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8204         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8205         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8206         0x0000ffff                                                              /* end                  */
8207     };
8208     IDirect3DVertexShader9 *vshader;
8209     IDirect3DPixelShader9 *shader, *shader_frac;
8210     IDirect3DSurface9 *surface = NULL, *backbuffer;
8211     const float quad[] = {
8212         -1.0,   -1.0,   0.1,    0.0,    0.0,
8213          1.0,   -1.0,   0.1,    1.0,    0.0,
8214         -1.0,    1.0,   0.1,    0.0,    1.0,
8215          1.0,    1.0,   0.1,    1.0,    1.0,
8216     };
8217     D3DLOCKED_RECT lr;
8218     float constant[4] = {1.0, 0.0, 320, 240};
8219     DWORD *pos;
8220
8221     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8222     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8223     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8224     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8225     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8226     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8227     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8228     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8229     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8230     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8231     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8232     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8233     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8234     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8235     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8236     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8237
8238     hr = IDirect3DDevice9_BeginScene(device);
8239     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8240     if(SUCCEEDED(hr)) {
8241         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8242         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8243         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8244         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8245         hr = IDirect3DDevice9_EndScene(device);
8246         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8247     }
8248
8249     /* This has to be pixel exact */
8250     color = getPixelColor(device, 319, 239);
8251     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8252     color = getPixelColor(device, 320, 239);
8253     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8254     color = getPixelColor(device, 319, 240);
8255     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8256     color = getPixelColor(device, 320, 240);
8257     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8258     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8259
8260     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8261                                              &surface, NULL);
8262     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8263     hr = IDirect3DDevice9_BeginScene(device);
8264     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8265     if(SUCCEEDED(hr)) {
8266         constant[2] = 16; constant[3] = 16;
8267         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8268         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8269         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8270         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8271         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8272         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8273         hr = IDirect3DDevice9_EndScene(device);
8274         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8275     }
8276     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8277     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8278
8279     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8280     color = *pos & 0x00ffffff;
8281     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8282     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8283     color = *pos & 0x00ffffff;
8284     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8285     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8286     color = *pos & 0x00ffffff;
8287     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8288     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8289     color = *pos & 0x00ffffff;
8290     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8291
8292     hr = IDirect3DSurface9_UnlockRect(surface);
8293     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8294
8295     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8296      * have full control over the multisampling setting inside this test
8297      */
8298     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8299     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8300     hr = IDirect3DDevice9_BeginScene(device);
8301     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8302     if(SUCCEEDED(hr)) {
8303         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8304         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8305         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8306         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8307         hr = IDirect3DDevice9_EndScene(device);
8308         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8309     }
8310     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8311     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8312
8313     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8314     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8315
8316     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8317     color = *pos & 0x00ffffff;
8318     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8319
8320     hr = IDirect3DSurface9_UnlockRect(surface);
8321     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8322
8323     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8324     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8325     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8326     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8327     IDirect3DPixelShader9_Release(shader);
8328     IDirect3DPixelShader9_Release(shader_frac);
8329     IDirect3DVertexShader9_Release(vshader);
8330     if(surface) IDirect3DSurface9_Release(surface);
8331     IDirect3DSurface9_Release(backbuffer);
8332 }
8333
8334 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8335 {
8336     D3DCOLOR color;
8337
8338     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8339     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8340     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8341     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8342     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8343
8344     ++r;
8345     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8346     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8347     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8348     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8349     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8350
8351     return TRUE;
8352 }
8353
8354 static void pointsize_test(IDirect3DDevice9 *device)
8355 {
8356     HRESULT hr;
8357     D3DCAPS9 caps;
8358     D3DMATRIX matrix;
8359     D3DMATRIX identity;
8360     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8361     DWORD color;
8362     IDirect3DSurface9 *rt, *backbuffer;
8363     IDirect3DTexture9 *tex1, *tex2;
8364     RECT rect = {0, 0, 128, 128};
8365     D3DLOCKED_RECT lr;
8366     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8367                                 0x00000000, 0x00000000};
8368     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8369                                 0x00000000, 0x0000ff00};
8370
8371     const float vertices[] = {
8372         64,     64,     0.1,
8373         128,    64,     0.1,
8374         192,    64,     0.1,
8375         256,    64,     0.1,
8376         320,    64,     0.1,
8377         384,    64,     0.1,
8378         448,    64,     0.1,
8379         512,    64,     0.1,
8380     };
8381
8382     /* 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 */
8383     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;
8384     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;
8385     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;
8386     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;
8387
8388     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;
8389     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;
8390     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;
8391     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;
8392
8393     memset(&caps, 0, sizeof(caps));
8394     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8395     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8396     if(caps.MaxPointSize < 32.0) {
8397         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8398         return;
8399     }
8400
8401     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8402     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8403     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8404     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8405     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8406     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8407     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8408     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8409
8410     hr = IDirect3DDevice9_BeginScene(device);
8411     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8412     if (SUCCEEDED(hr))
8413     {
8414         ptsize = 15.0;
8415         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8416         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8417         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8418         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8419
8420         ptsize = 31.0;
8421         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8422         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8423         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8424         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8425
8426         ptsize = 30.75;
8427         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8428         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8429         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8430         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8431
8432         if (caps.MaxPointSize >= 63.0)
8433         {
8434             ptsize = 63.0;
8435             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8436             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8437             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8438             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8439
8440             ptsize = 62.75;
8441             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8442             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8443             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8444             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8445         }
8446
8447         ptsize = 1.0;
8448         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8449         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8450         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8451         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8452
8453         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8454         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8455         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8456         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8457
8458         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8459         ptsize = 15.0;
8460         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8461         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8462         ptsize = 1.0;
8463         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8464         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8465         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8466         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8467
8468         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8469         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8470
8471         /* pointsize < pointsize_min < pointsize_max?
8472          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8473         ptsize = 1.0;
8474         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8475         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8476         ptsize = 15.0;
8477         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8478         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8479         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8480         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8481
8482         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8483         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8484
8485         hr = IDirect3DDevice9_EndScene(device);
8486         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8487     }
8488
8489     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8490     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8491     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8492
8493     if (caps.MaxPointSize >= 63.0)
8494     {
8495         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8496         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8497     }
8498
8499     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8500     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8501     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8502     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8503     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8504
8505     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8506
8507     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8508      * generates texture coordinates for the point(result: Yes, it does)
8509      *
8510      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8511      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8512      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8513      */
8514     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8515     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8516
8517     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8518     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8519     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8520     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8521     memset(&lr, 0, sizeof(lr));
8522     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8523     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8524     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8525     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8526     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8527     memset(&lr, 0, sizeof(lr));
8528     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8529     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8530     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8531     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8532     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8533     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8534     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8535     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8536     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8537     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8538     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8539     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8540     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8541     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8542     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8543     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8544     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8545     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8546     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8547
8548     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8549     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8550     ptsize = 32.0;
8551     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8552     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8553
8554     hr = IDirect3DDevice9_BeginScene(device);
8555     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8556     if(SUCCEEDED(hr))
8557     {
8558         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8559         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8560         hr = IDirect3DDevice9_EndScene(device);
8561         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8562     }
8563
8564     color = getPixelColor(device, 64-4, 64-4);
8565     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8566     color = getPixelColor(device, 64-4, 64+4);
8567     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8568     color = getPixelColor(device, 64+4, 64+4);
8569     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8570     color = getPixelColor(device, 64+4, 64-4);
8571     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8572     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8573
8574     U(matrix).m[0][0] =  1.0f / 64.0f;
8575     U(matrix).m[1][1] = -1.0f / 64.0f;
8576     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8577     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8578
8579     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8580     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8581
8582     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8583             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8584     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8585
8586     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8587     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8588     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
8589     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
8590
8591     hr = IDirect3DDevice9_BeginScene(device);
8592     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8593     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8594     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8595     hr = IDirect3DDevice9_EndScene(device);
8596     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8597
8598     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
8599     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
8600     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8601     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8602     IDirect3DSurface9_Release(backbuffer);
8603     IDirect3DSurface9_Release(rt);
8604
8605     color = getPixelColor(device, 64-4, 64-4);
8606     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
8607             "Expected color 0x00ff0000, got 0x%08x.\n", color);
8608     color = getPixelColor(device, 64+4, 64-4);
8609     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
8610             "Expected color 0x00ffff00, got 0x%08x.\n", color);
8611     color = getPixelColor(device, 64-4, 64+4);
8612     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
8613             "Expected color 0x00000000, got 0x%08x.\n", color);
8614     color = getPixelColor(device, 64+4, 64+4);
8615     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8616             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8617
8618     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8619     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8620
8621     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8622     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8623     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8624     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8625     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8626     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8627     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8628     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8629     IDirect3DTexture9_Release(tex1);
8630     IDirect3DTexture9_Release(tex2);
8631
8632     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8633     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8634     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8635     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8636     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8637     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8638 }
8639
8640 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8641 {
8642     static const DWORD vshader_code[] =
8643     {
8644         0xfffe0300,                                                             /* vs_3_0                     */
8645         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0            */
8646         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0            */
8647         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                 */
8648         0x0000ffff                                                              /* end                        */
8649     };
8650     static const DWORD pshader_code1[] =
8651     {
8652         0xffff0300,                                                             /* ps_3_0                     */
8653         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8654         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
8655         0x0000ffff                                                              /* end                        */
8656     };
8657     static const DWORD pshader_code2[] =
8658     {
8659         0xffff0300,                                                             /* ps_3_0                     */
8660         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8661         0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
8662         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
8663         0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1                */
8664         0x0000ffff                                                              /* end                        */
8665     };
8666
8667     HRESULT hr;
8668     IDirect3DVertexShader9 *vs;
8669     IDirect3DPixelShader9 *ps1, *ps2;
8670     IDirect3DTexture9 *tex1, *tex2;
8671     IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
8672     D3DCAPS9 caps;
8673     DWORD color;
8674     UINT i, j;
8675     float quad[] = {
8676        -1.0,   -1.0,    0.1,
8677         1.0,   -1.0,    0.1,
8678        -1.0,    1.0,    0.1,
8679         1.0,    1.0,    0.1,
8680     };
8681     float texquad[] = {
8682        -1.0,   -1.0,    0.1,    0.0,    0.0,
8683         0.0,   -1.0,    0.1,    1.0,    0.0,
8684        -1.0,    1.0,    0.1,    0.0,    1.0,
8685         0.0,    1.0,    0.1,    1.0,    1.0,
8686
8687         0.0,   -1.0,    0.1,    0.0,    0.0,
8688         1.0,   -1.0,    0.1,    1.0,    0.0,
8689         0.0,    1.0,    0.1,    0.0,    1.0,
8690         1.0,    1.0,    0.1,    1.0,    1.0,
8691     };
8692
8693     memset(&caps, 0, sizeof(caps));
8694     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8695     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8696     if(caps.NumSimultaneousRTs < 2) {
8697         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8698         return;
8699     }
8700
8701     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8702     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8703
8704     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
8705             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
8706     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
8707
8708     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8709             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8710     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8711     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8712             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8713     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8714     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
8715     ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
8716     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
8717     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
8718     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
8719     ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
8720
8721     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8722     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8723     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8724     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8725     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8726     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8727
8728     hr = IDirect3DDevice9_SetVertexShader(device, vs);
8729     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8730     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8731     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8732     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8733     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8734     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8735     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8736
8737     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8738     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8739     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8740     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8741     color = getPixelColorFromSurface(readback, 8, 8);
8742     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8743             "Expected color 0x000000ff, got 0x%08x.\n", color);
8744     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8745     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8746     color = getPixelColorFromSurface(readback, 8, 8);
8747     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8748             "Expected color 0x000000ff, got 0x%08x.\n", color);
8749
8750     /* Render targets not written by the pixel shader should be unmodified. */
8751     hr = IDirect3DDevice9_SetPixelShader(device, ps1);
8752     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8753     hr = IDirect3DDevice9_BeginScene(device);
8754     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8755     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8756     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8757     hr = IDirect3DDevice9_EndScene(device);
8758     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8759     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8760     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8761     color = getPixelColorFromSurface(readback, 8, 8);
8762     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8763             "Expected color 0xff00ff00, got 0x%08x.\n", color);
8764     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8765     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8766     for (i = 6; i < 10; ++i)
8767     {
8768         for (j = 6; j < 10; ++j)
8769         {
8770             color = getPixelColorFromSurface(readback, j, i);
8771             ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8772                     "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
8773         }
8774     }
8775
8776     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8777     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8778     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8779     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8780     color = getPixelColorFromSurface(readback, 8, 8);
8781     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8782             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8783     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8784     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8785     color = getPixelColorFromSurface(readback, 8, 8);
8786     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8787             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8788
8789     hr = IDirect3DDevice9_SetPixelShader(device, ps2);
8790     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8791
8792     hr = IDirect3DDevice9_BeginScene(device);
8793     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8794     if(SUCCEEDED(hr)) {
8795         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8796         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8797
8798         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8799         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8800         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8801         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8802         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8803         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8804         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8805         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8806         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8807         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8808
8809         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8810         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8811         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8812         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8813
8814         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8815         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8816         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8817         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8818
8819         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8820         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8821
8822         hr = IDirect3DDevice9_EndScene(device);
8823         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8824     }
8825
8826     color = getPixelColor(device, 160, 240);
8827     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8828     color = getPixelColor(device, 480, 240);
8829     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8830     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8831
8832     IDirect3DPixelShader9_Release(ps2);
8833     IDirect3DPixelShader9_Release(ps1);
8834     IDirect3DVertexShader9_Release(vs);
8835     IDirect3DTexture9_Release(tex1);
8836     IDirect3DTexture9_Release(tex2);
8837     IDirect3DSurface9_Release(surf1);
8838     IDirect3DSurface9_Release(surf2);
8839     IDirect3DSurface9_Release(backbuf);
8840     IDirect3DSurface9_Release(readback);
8841 }
8842
8843 struct formats {
8844     const char *fmtName;
8845     D3DFORMAT textureFormat;
8846     DWORD resultColorBlending;
8847     DWORD resultColorNoBlending;
8848 };
8849
8850 static const struct formats test_formats[] = {
8851   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8852   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8853   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8854   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8855   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8856   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8857   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8858   { NULL, 0 }
8859 };
8860
8861 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8862 {
8863     HRESULT hr;
8864     IDirect3DTexture9 *offscreenTexture = NULL;
8865     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8866     IDirect3D9 *d3d = NULL;
8867     DWORD color;
8868     DWORD r0, g0, b0, r1, g1, b1;
8869     int fmt_index;
8870
8871     static const float quad[][5] = {
8872         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8873         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8874         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8875         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8876     };
8877
8878     /* Quad with R=0x10, G=0x20 */
8879     static const struct vertex quad1[] = {
8880         {-1.0f, -1.0f, 0.1f, 0x80102000},
8881         {-1.0f,  1.0f, 0.1f, 0x80102000},
8882         { 1.0f, -1.0f, 0.1f, 0x80102000},
8883         { 1.0f,  1.0f, 0.1f, 0x80102000},
8884     };
8885
8886     /* Quad with R=0x20, G=0x10 */
8887     static const struct vertex quad2[] = {
8888         {-1.0f, -1.0f, 0.1f, 0x80201000},
8889         {-1.0f,  1.0f, 0.1f, 0x80201000},
8890         { 1.0f, -1.0f, 0.1f, 0x80201000},
8891         { 1.0f,  1.0f, 0.1f, 0x80201000},
8892     };
8893
8894     IDirect3DDevice9_GetDirect3D(device, &d3d);
8895
8896     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8897     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8898     if(!backbuffer) {
8899         goto out;
8900     }
8901
8902     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8903     {
8904         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8905
8906         if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
8907                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
8908         {
8909             skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
8910             continue;
8911         }
8912
8913         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8914         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8915
8916         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8917         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8918         if(!offscreenTexture) {
8919             continue;
8920         }
8921
8922         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8923         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8924         if(!offscreen) {
8925             continue;
8926         }
8927
8928         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8929         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8930
8931         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8932         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8933         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8934         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8935         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8936         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8937         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8938         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8939         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8940         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8941
8942         /* Below we will draw two quads with different colors and try to blend them together.
8943          * The result color is compared with the expected outcome.
8944          */
8945         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8946             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8947             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8948             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8949             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8950
8951             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8952             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8953
8954             /* Draw a quad using color 0x0010200 */
8955             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8956             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8957             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8958             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8959             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8960             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8961
8962             /* Draw a quad using color 0x0020100 */
8963             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8964             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8965             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8966             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8967             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8968             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8969
8970             /* We don't want to blend the result on the backbuffer */
8971             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8972             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8973
8974             /* Prepare rendering the 'blended' texture quad to the backbuffer */
8975             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8976             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8977             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8978             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8979
8980             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8981             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8982
8983             /* This time with the texture */
8984             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8985             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8986
8987             IDirect3DDevice9_EndScene(device);
8988         }
8989
8990         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8991             /* Compare the color of the center quad with our expectation */
8992             color = getPixelColor(device, 320, 240);
8993             r0 = (color & 0x00ff0000) >> 16;
8994             g0 = (color & 0x0000ff00) >>  8;
8995             b0 = (color & 0x000000ff) >>  0;
8996
8997             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8998             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
8999             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9000
9001             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9002                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9003                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9004                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9005         } else {
9006             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9007              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9008              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9009             color = getPixelColor(device, 320, 240);
9010             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);
9011         }
9012         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9013
9014         IDirect3DDevice9_SetTexture(device, 0, NULL);
9015         if(offscreenTexture) {
9016             IDirect3DTexture9_Release(offscreenTexture);
9017         }
9018         if(offscreen) {
9019             IDirect3DSurface9_Release(offscreen);
9020         }
9021     }
9022
9023 out:
9024     /* restore things */
9025     if(backbuffer) {
9026         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9027         IDirect3DSurface9_Release(backbuffer);
9028     }
9029 }
9030
9031 static void tssargtemp_test(IDirect3DDevice9 *device)
9032 {
9033     HRESULT hr;
9034     DWORD color;
9035     static const struct vertex quad[] = {
9036         {-1.0,     -1.0,    0.1,    0x00ff0000},
9037         { 1.0,     -1.0,    0.1,    0x00ff0000},
9038         {-1.0,      1.0,    0.1,    0x00ff0000},
9039         { 1.0,      1.0,    0.1,    0x00ff0000}
9040     };
9041     D3DCAPS9 caps;
9042
9043     memset(&caps, 0, sizeof(caps));
9044     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9045     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9046     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9047         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9048         return;
9049     }
9050
9051     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9052     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9053
9054     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9055     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9056     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9057     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9058
9059     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9060     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9061     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9062     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9063     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9064     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9065
9066     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9067     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9068     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9069     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9070     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9071     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9072
9073     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9074     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9075
9076     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9077     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9078     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9079     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9080
9081     hr = IDirect3DDevice9_BeginScene(device);
9082     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9083     if(SUCCEEDED(hr)) {
9084         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9085         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9086         hr = IDirect3DDevice9_EndScene(device);
9087         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9088     }
9089     color = getPixelColor(device, 320, 240);
9090     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9091     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9092
9093     /* Set stage 1 back to default */
9094     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9095     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9096     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9097     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9098     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9099     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9100     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9101     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9102     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9103     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9104 }
9105
9106 struct testdata
9107 {
9108     DWORD idxVertex; /* number of instances in the first stream */
9109     DWORD idxColor; /* number of instances in the second stream */
9110     DWORD idxInstance; /* should be 1 ?? */
9111     DWORD color1; /* color 1 instance */
9112     DWORD color2; /* color 2 instance */
9113     DWORD color3; /* color 3 instance */
9114     DWORD color4; /* color 4 instance */
9115     WORD strVertex; /* specify which stream to use 0-2*/
9116     WORD strColor;
9117     WORD strInstance;
9118 };
9119
9120 static const struct testdata testcases[]=
9121 {
9122     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9123     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9124     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9125     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9126     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  4 */
9127     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9128     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9129     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9130     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  8 */
9131     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /*  9 */
9132     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9133     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9134     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9135     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9136 /*
9137     This draws one instance on some machines, no instance on others
9138     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9139 */
9140 /*
9141     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9142     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9143 */
9144 };
9145
9146 /* Drawing Indexed Geometry with instances*/
9147 static void stream_test(IDirect3DDevice9 *device)
9148 {
9149     IDirect3DVertexBuffer9 *vb = NULL;
9150     IDirect3DVertexBuffer9 *vb2 = NULL;
9151     IDirect3DVertexBuffer9 *vb3 = NULL;
9152     IDirect3DIndexBuffer9 *ib = NULL;
9153     IDirect3DVertexDeclaration9 *pDecl = NULL;
9154     IDirect3DVertexShader9 *shader = NULL;
9155     HRESULT hr;
9156     BYTE *data;
9157     DWORD color;
9158     DWORD ind;
9159     unsigned i;
9160
9161     const DWORD shader_code[] =
9162     {
9163         0xfffe0101,                                     /* vs_1_1 */
9164         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9165         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9166         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9167         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9168         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9169         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9170         0x0000ffff
9171     };
9172
9173     const float quad[][3] =
9174     {
9175         {-0.5f, -0.5f,  1.1f}, /*0 */
9176         {-0.5f,  0.5f,  1.1f}, /*1 */
9177         { 0.5f, -0.5f,  1.1f}, /*2 */
9178         { 0.5f,  0.5f,  1.1f}, /*3 */
9179     };
9180
9181     const float vertcolor[][4] =
9182     {
9183         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9184         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9185         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9186         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9187     };
9188
9189     /* 4 position for 4 instances */
9190     const float instancepos[][3] =
9191     {
9192         {-0.6f,-0.6f, 0.0f},
9193         { 0.6f,-0.6f, 0.0f},
9194         { 0.6f, 0.6f, 0.0f},
9195         {-0.6f, 0.6f, 0.0f},
9196     };
9197
9198     short indices[] = {0, 1, 2, 1, 2, 3};
9199
9200     D3DVERTEXELEMENT9 decl[] =
9201     {
9202         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9203         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9204         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9205         D3DDECL_END()
9206     };
9207
9208     /* set the default value because it isn't done in wine? */
9209     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9210     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9211
9212     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9213     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9214     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9215
9216     /* check wrong cases */
9217     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9218     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9219     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9220     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9221     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9222     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9223     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9224     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9225     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9226     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9227     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9228     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9229     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9230     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9231     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9232     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9233     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9234     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9235     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9236     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9237
9238     /* set the default value back */
9239     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9240     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9241
9242     /* create all VertexBuffers*/
9243     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9244     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9245     if(!vb) {
9246         skip("Failed to create a vertex buffer\n");
9247         return;
9248     }
9249     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9250     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9251     if(!vb2) {
9252         skip("Failed to create a vertex buffer\n");
9253         goto out;
9254     }
9255     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9256     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9257     if(!vb3) {
9258         skip("Failed to create a vertex buffer\n");
9259         goto out;
9260     }
9261
9262     /* create IndexBuffer*/
9263     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9264     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9265     if(!ib) {
9266         skip("Failed to create a index buffer\n");
9267         goto out;
9268     }
9269
9270     /* copy all Buffers (Vertex + Index)*/
9271     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9272     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9273     memcpy(data, quad, sizeof(quad));
9274     hr = IDirect3DVertexBuffer9_Unlock(vb);
9275     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9276     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9277     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9278     memcpy(data, vertcolor, sizeof(vertcolor));
9279     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9280     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9281     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9282     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9283     memcpy(data, instancepos, sizeof(instancepos));
9284     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9285     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9286     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9287     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9288     memcpy(data, indices, sizeof(indices));
9289     hr = IDirect3DIndexBuffer9_Unlock(ib);
9290     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9291
9292     /* create VertexShader */
9293     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9294     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9295     if(!shader) {
9296         skip("Failed to create a vetex shader\n");
9297         goto out;
9298     }
9299
9300     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9301     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9302
9303     hr = IDirect3DDevice9_SetIndices(device, ib);
9304     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9305
9306     /* run all tests */
9307     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9308     {
9309         struct testdata act = testcases[i];
9310         decl[0].Stream = act.strVertex;
9311         decl[1].Stream = act.strColor;
9312         decl[2].Stream = act.strInstance;
9313         /* create VertexDeclarations */
9314         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9315         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9316
9317         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9318         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9319
9320         hr = IDirect3DDevice9_BeginScene(device);
9321         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9322         if(SUCCEEDED(hr))
9323         {
9324             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9325             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9326
9327             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9328             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9329             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9330             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9331
9332             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9333             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9334             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9335             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9336
9337             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9338             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9339             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9340             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9341
9342             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9343             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9344             hr = IDirect3DDevice9_EndScene(device);
9345             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9346
9347             /* set all StreamSource && StreamSourceFreq back to default */
9348             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9349             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9350             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9351             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9352             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9353             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9354             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9355             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9356             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9357             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9358             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9359             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9360         }
9361
9362         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9363         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9364
9365         color = getPixelColor(device, 160, 360);
9366         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9367         color = getPixelColor(device, 480, 360);
9368         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9369         color = getPixelColor(device, 480, 120);
9370         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9371         color = getPixelColor(device, 160, 120);
9372         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9373
9374         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9375         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9376     }
9377
9378     hr = IDirect3DDevice9_SetIndices(device, NULL);
9379     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9380
9381 out:
9382     if(vb) IDirect3DVertexBuffer9_Release(vb);
9383     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9384     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9385     if(ib)IDirect3DIndexBuffer9_Release(ib);
9386     if(shader)IDirect3DVertexShader9_Release(shader);
9387 }
9388
9389 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9390     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9391     IDirect3DTexture9 *dsttex = NULL;
9392     HRESULT hr;
9393     DWORD color;
9394     D3DRECT r1 = {0,  0,  50,  50 };
9395     D3DRECT r2 = {50, 0,  100, 50 };
9396     D3DRECT r3 = {50, 50, 100, 100};
9397     D3DRECT r4 = {0,  50,  50, 100};
9398     const float quad[] = {
9399         -1.0,   -1.0,   0.1,    0.0,    0.0,
9400          1.0,   -1.0,   0.1,    1.0,    0.0,
9401         -1.0,    1.0,   0.1,    0.0,    1.0,
9402          1.0,    1.0,   0.1,    1.0,    1.0,
9403     };
9404
9405     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9406     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9407
9408     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9409     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9410     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9411     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9412
9413     if(!src || !dsttex) {
9414         skip("One or more test resources could not be created\n");
9415         goto cleanup;
9416     }
9417
9418     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9419     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9420
9421     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9422     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9423
9424     /* Clear the StretchRect destination for debugging */
9425     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9426     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9427     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9428     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9429
9430     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9431     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9432
9433     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9434     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9435     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9436     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9437     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9438     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9439     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9440     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9441
9442     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9443      * the target -> texture GL blit path
9444      */
9445     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9446     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9447     IDirect3DSurface9_Release(dst);
9448
9449     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9450     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9451
9452     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9453     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9454     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9455     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9456     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9457     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9458     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9459     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9460
9461     hr = IDirect3DDevice9_BeginScene(device);
9462     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9463     if(SUCCEEDED(hr)) {
9464         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9465         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9466         hr = IDirect3DDevice9_EndScene(device);
9467         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9468     }
9469
9470     color = getPixelColor(device, 160, 360);
9471     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9472     color = getPixelColor(device, 480, 360);
9473     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9474     color = getPixelColor(device, 480, 120);
9475     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9476     color = getPixelColor(device, 160, 120);
9477     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9478     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9479     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9480
9481     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9482     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9483     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9484     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9485
9486 cleanup:
9487     if(src) IDirect3DSurface9_Release(src);
9488     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9489     if(dsttex) IDirect3DTexture9_Release(dsttex);
9490 }
9491
9492 static void texop_test(IDirect3DDevice9 *device)
9493 {
9494     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9495     IDirect3DTexture9 *texture = NULL;
9496     D3DLOCKED_RECT locked_rect;
9497     D3DCOLOR color;
9498     D3DCAPS9 caps;
9499     HRESULT hr;
9500     unsigned i;
9501
9502     static const struct {
9503         float x, y, z;
9504         float s, t;
9505         D3DCOLOR diffuse;
9506     } quad[] = {
9507         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9508         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9509         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9510         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9511     };
9512
9513     static const D3DVERTEXELEMENT9 decl_elements[] = {
9514         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9515         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9516         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9517         D3DDECL_END()
9518     };
9519
9520     static const struct {
9521         D3DTEXTUREOP op;
9522         const char *name;
9523         DWORD caps_flag;
9524         D3DCOLOR result;
9525     } test_data[] = {
9526         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9527         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9528         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9529         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9530         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9531         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9532         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9533         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9534         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9535         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9536         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9537         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9538         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9539         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9540         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9541         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9542         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9543         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9544         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9545         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9546         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9547         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9548         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9549     };
9550
9551     memset(&caps, 0, sizeof(caps));
9552     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9553     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9554
9555     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9556     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9557     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9558     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9559
9560     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9561     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9562     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9563     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9564     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9565     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9566     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9567     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9568     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9569
9570     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9571     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9572     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9573     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9574     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9575     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9576
9577     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9578     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9579
9580     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9581     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9582     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9583     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9584     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9585     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9586
9587     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9588     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9589
9590     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9591     {
9592         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9593         {
9594             skip("tex operation %s not supported\n", test_data[i].name);
9595             continue;
9596         }
9597
9598         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9599         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9600
9601         hr = IDirect3DDevice9_BeginScene(device);
9602         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9603
9604         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9605         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9606
9607         hr = IDirect3DDevice9_EndScene(device);
9608         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9609
9610         color = getPixelColor(device, 320, 240);
9611         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9612                 test_data[i].name, color, test_data[i].result);
9613
9614         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9615         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9616     }
9617
9618     if (texture) IDirect3DTexture9_Release(texture);
9619     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9620 }
9621
9622 static void yuv_color_test(IDirect3DDevice9 *device) {
9623     HRESULT hr;
9624     IDirect3DSurface9 *surface = NULL, *target = NULL;
9625     unsigned int fmt, i;
9626     D3DFORMAT format;
9627     const char *fmt_string;
9628     D3DLOCKED_RECT lr;
9629     IDirect3D9 *d3d;
9630     HRESULT color;
9631     DWORD ref_color_left, ref_color_right;
9632
9633     struct {
9634         DWORD in;           /* The input color */
9635         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9636         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9637         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9638         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9639     } test_data[] = {
9640     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9641      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9642      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9643      * that
9644      */
9645       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9646       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9647       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9648       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9649       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9650       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9651       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9652       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9653       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9654       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9655       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9656       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9657       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9658       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9659
9660       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9661       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9662       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9663       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9664     };
9665
9666     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9667     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9668     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9669     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9670
9671     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9672     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9673
9674     for(fmt = 0; fmt < 2; fmt++) {
9675         if(fmt == 0) {
9676             format = D3DFMT_UYVY;
9677             fmt_string = "D3DFMT_UYVY";
9678         } else {
9679             format = D3DFMT_YUY2;
9680             fmt_string = "D3DFMT_YUY2";
9681         }
9682
9683         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9684                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9685                        */
9686         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9687                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9688             skip("%s is not supported\n", fmt_string);
9689             continue;
9690         }
9691
9692         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9693         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9694         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9695
9696         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9697             if(fmt == 0) {
9698                 ref_color_left = test_data[i].uyvy_left;
9699                 ref_color_right = test_data[i].uyvy_right;
9700             } else {
9701                 ref_color_left = test_data[i].yuy2_left;
9702                 ref_color_right = test_data[i].yuy2_right;
9703             }
9704
9705             memset(&lr, 0, sizeof(lr));
9706             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9707             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9708             *((DWORD *) lr.pBits) = test_data[i].in;
9709             hr = IDirect3DSurface9_UnlockRect(surface);
9710             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9711
9712             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9713             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9714             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9715             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9716
9717             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9718              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9719              * want to add tests for the filtered pixels as well.
9720              *
9721              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9722              * differently, so we need a max diff of 16
9723              */
9724             color = getPixelColor(device, 40, 240);
9725
9726             /* Newer versions of the Nvidia Windows driver mix up the U and V channels, breaking all the tests
9727              * where U != V. Skip the entire test if this bug in this case
9728              */
9729             if (broken(test_data[i].in == 0xff000000 && color == 0x00008800 && format == D3DFMT_UYVY))
9730             {
9731                 skip("Nvidia channel confusion bug detected, skipping YUV tests\n");
9732                 IDirect3DSurface9_Release(surface);
9733                 goto out;
9734             }
9735
9736             ok(color_match(color, ref_color_left, 18),
9737                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9738                test_data[i].in, color, ref_color_left, fmt_string);
9739             color = getPixelColor(device, 600, 240);
9740             ok(color_match(color, ref_color_right, 18),
9741                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9742                test_data[i].in, color, ref_color_right, fmt_string);
9743             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9744             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9745         }
9746         IDirect3DSurface9_Release(surface);
9747     }
9748
9749 out:
9750     IDirect3DSurface9_Release(target);
9751     IDirect3D9_Release(d3d);
9752 }
9753
9754 static void texop_range_test(IDirect3DDevice9 *device)
9755 {
9756     static const struct {
9757         float x, y, z;
9758         D3DCOLOR diffuse;
9759     } quad[] = {
9760         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9761         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9762         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9763         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9764     };
9765     HRESULT hr;
9766     IDirect3DTexture9 *texture;
9767     D3DLOCKED_RECT locked_rect;
9768     D3DCAPS9 caps;
9769     DWORD color;
9770
9771     /* We need ADD and SUBTRACT operations */
9772     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9773     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9774     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9775         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9776         return;
9777     }
9778     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9779         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9780         return;
9781     }
9782
9783     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9784     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9785     /* Stage 1: result = diffuse(=1.0) + diffuse
9786      * stage 2: result = result - tfactor(= 0.5)
9787      */
9788     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9789     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9790     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9791     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9792     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9793     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9794     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9795     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9796     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9797     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9798     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9799     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9800     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9801     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9802
9803     hr = IDirect3DDevice9_BeginScene(device);
9804     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9805     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9806     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9807     hr = IDirect3DDevice9_EndScene(device);
9808     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9809
9810     color = getPixelColor(device, 320, 240);
9811     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9812        color);
9813     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9814     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9815
9816     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9817     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9818     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9819     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9820     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9821     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9822     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9823     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9824     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9825
9826     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9827      * stage 2: result = result + diffuse(1.0)
9828      */
9829     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9830     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9831     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9832     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9833     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9834     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9835     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9836     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9837     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9838     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9839     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9840     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9841     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9842     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9843
9844     hr = IDirect3DDevice9_BeginScene(device);
9845     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9846     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9847     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9848     hr = IDirect3DDevice9_EndScene(device);
9849     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9850
9851     color = getPixelColor(device, 320, 240);
9852     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9853        color);
9854     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9855     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9856
9857     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9858     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9859     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9860     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9861     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9862     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9863     IDirect3DTexture9_Release(texture);
9864 }
9865
9866 static void alphareplicate_test(IDirect3DDevice9 *device) {
9867     struct vertex quad[] = {
9868         { -1.0,    -1.0,    0.1,    0x80ff00ff },
9869         {  1.0,    -1.0,    0.1,    0x80ff00ff },
9870         { -1.0,     1.0,    0.1,    0x80ff00ff },
9871         {  1.0,     1.0,    0.1,    0x80ff00ff },
9872     };
9873     HRESULT hr;
9874     DWORD color;
9875
9876     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9877     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9878
9879     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9880     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9881
9882     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9883     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9884     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9885     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9886
9887     hr = IDirect3DDevice9_BeginScene(device);
9888     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9889     if(SUCCEEDED(hr)) {
9890         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9891         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9892         hr = IDirect3DDevice9_EndScene(device);
9893         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9894     }
9895
9896     color = getPixelColor(device, 320, 240);
9897     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9898        color);
9899     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9900     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9901
9902     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9903     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9904
9905 }
9906
9907 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9908     HRESULT hr;
9909     D3DCAPS9 caps;
9910     DWORD color;
9911     struct vertex quad[] = {
9912         { -1.0,    -1.0,    0.1,    0x408080c0 },
9913         {  1.0,    -1.0,    0.1,    0x408080c0 },
9914         { -1.0,     1.0,    0.1,    0x408080c0 },
9915         {  1.0,     1.0,    0.1,    0x408080c0 },
9916     };
9917
9918     memset(&caps, 0, sizeof(caps));
9919     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9920     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9921     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9922         skip("D3DTOP_DOTPRODUCT3 not supported\n");
9923         return;
9924     }
9925
9926     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9927     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9928
9929     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9930     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9931
9932     /* dp3_x4 r0, diffuse_bias, tfactor_bias
9933      * mov r0.a, diffuse.a
9934      * mov r0, r0.a
9935      *
9936      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9937      * 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
9938      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9939      */
9940     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9941     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9942     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9943     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9944     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9945     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9946     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9947     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9948     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9949     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9950     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9951     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9952     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9953     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9954     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9955     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9956     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9957     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9958
9959     hr = IDirect3DDevice9_BeginScene(device);
9960     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9961     if(SUCCEEDED(hr)) {
9962         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9963         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9964         hr = IDirect3DDevice9_EndScene(device);
9965         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9966     }
9967
9968     color = getPixelColor(device, 320, 240);
9969     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9970        color);
9971     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9972     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9973
9974     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9975     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9976     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9977     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9978     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9979     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9980 }
9981
9982 static void zwriteenable_test(IDirect3DDevice9 *device) {
9983     HRESULT hr;
9984     DWORD color;
9985     struct vertex quad1[] = {
9986         { -1.0,  -1.0,  0.1,    0x00ff0000},
9987         { -1.0,   1.0,  0.1,    0x00ff0000},
9988         {  1.0,  -1.0,  0.1,    0x00ff0000},
9989         {  1.0,   1.0,  0.1,    0x00ff0000},
9990     };
9991     struct vertex quad2[] = {
9992         { -1.0,  -1.0,  0.9,    0x0000ff00},
9993         { -1.0,   1.0,  0.9,    0x0000ff00},
9994         {  1.0,  -1.0,  0.9,    0x0000ff00},
9995         {  1.0,   1.0,  0.9,    0x0000ff00},
9996     };
9997
9998     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9999     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10000
10001     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10002     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10003     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10004     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10005     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10006     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10007     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10008     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10009
10010     hr = IDirect3DDevice9_BeginScene(device);
10011     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10012     if(SUCCEEDED(hr)) {
10013         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10014          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10015          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10016          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10017          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10018          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10019          */
10020         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10021         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10022         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10023         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10024         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10025         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10026
10027         hr = IDirect3DDevice9_EndScene(device);
10028         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10029     }
10030
10031     color = getPixelColor(device, 320, 240);
10032     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10033        color);
10034     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10035     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10036
10037     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10038     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10039 }
10040
10041 static void alphatest_test(IDirect3DDevice9 *device) {
10042 #define ALPHATEST_PASSED 0x0000ff00
10043 #define ALPHATEST_FAILED 0x00ff0000
10044     struct {
10045         D3DCMPFUNC  func;
10046         DWORD       color_less;
10047         DWORD       color_equal;
10048         DWORD       color_greater;
10049     } testdata[] = {
10050         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10051         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10052         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10053         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10054         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10055         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10056         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10057         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10058     };
10059     unsigned int i, j;
10060     HRESULT hr;
10061     DWORD color;
10062     struct vertex quad[] = {
10063         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10064         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10065         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10066         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10067     };
10068     D3DCAPS9 caps;
10069
10070     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10071     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10072     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10073     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10074
10075     for(j = 0; j < 2; j++) {
10076         if(j == 1) {
10077             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10078              * the alpha test either for performance reasons(floating point RTs) or to work
10079              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10080              * codepath for ffp and shader in this case, and the test should cover both
10081              */
10082             IDirect3DPixelShader9 *ps;
10083             DWORD shader_code[] = {
10084                 0xffff0101,                                 /* ps_1_1           */
10085                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10086                 0x0000ffff                                  /* end              */
10087             };
10088             memset(&caps, 0, sizeof(caps));
10089             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10090             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10091             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10092                 break;
10093             }
10094
10095             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10096             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10097             IDirect3DDevice9_SetPixelShader(device, ps);
10098             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10099             IDirect3DPixelShader9_Release(ps);
10100         }
10101
10102         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10103             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10104             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10105
10106             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10107             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10108             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10109             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10110             hr = IDirect3DDevice9_BeginScene(device);
10111             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10112             if(SUCCEEDED(hr)) {
10113                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10114                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10115                 hr = IDirect3DDevice9_EndScene(device);
10116                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10117             }
10118             color = getPixelColor(device, 320, 240);
10119             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10120             color, testdata[i].color_less, testdata[i].func);
10121             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10122             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10123
10124             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10125             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10126             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10127             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10128             hr = IDirect3DDevice9_BeginScene(device);
10129             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10130             if(SUCCEEDED(hr)) {
10131                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10132                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10133                 hr = IDirect3DDevice9_EndScene(device);
10134                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10135             }
10136             color = getPixelColor(device, 320, 240);
10137             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10138             color, testdata[i].color_equal, testdata[i].func);
10139             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10140             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10141
10142             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10143             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10144             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10145             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10146             hr = IDirect3DDevice9_BeginScene(device);
10147             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10148             if(SUCCEEDED(hr)) {
10149                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10150                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10151                 hr = IDirect3DDevice9_EndScene(device);
10152                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10153             }
10154             color = getPixelColor(device, 320, 240);
10155             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10156             color, testdata[i].color_greater, testdata[i].func);
10157             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10158             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10159         }
10160     }
10161
10162     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10163     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10164     IDirect3DDevice9_SetPixelShader(device, NULL);
10165     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10166 }
10167
10168 static void sincos_test(IDirect3DDevice9 *device) {
10169     const DWORD sin_shader_code[] = {
10170         0xfffe0200,                                                                 /* vs_2_0                       */
10171         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10172         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10173         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10174         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10175         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10176         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10177         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10178         0x0000ffff                                                                  /* end                          */
10179     };
10180     const DWORD cos_shader_code[] = {
10181         0xfffe0200,                                                                 /* vs_2_0                       */
10182         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10183         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10184         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10185         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10186         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10187         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10188         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10189         0x0000ffff                                                                  /* end                          */
10190     };
10191     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10192     HRESULT hr;
10193     struct {
10194         float x, y, z;
10195     } data[1280];
10196     unsigned int i;
10197     float sincosc1[4] = {D3DSINCOSCONST1};
10198     float sincosc2[4] = {D3DSINCOSCONST2};
10199
10200     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10201     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10202
10203     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10204     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10205     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10206     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10207     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10208     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10209     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10210     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10211     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10212     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10213
10214     /* Generate a point from -1 to 1 every 0.5 pixels */
10215     for(i = 0; i < 1280; i++) {
10216         data[i].x = (-640.0 + i) / 640.0;
10217         data[i].y = 0.0;
10218         data[i].z = 0.1;
10219     }
10220
10221     hr = IDirect3DDevice9_BeginScene(device);
10222     if(SUCCEEDED(hr)) {
10223         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10224         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10225         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10226         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10227
10228         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10229         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10230         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10231         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10232
10233         hr = IDirect3DDevice9_EndScene(device);
10234         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10235     }
10236     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10237     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10238     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10239
10240     IDirect3DDevice9_SetVertexShader(device, NULL);
10241     IDirect3DVertexShader9_Release(sin_shader);
10242     IDirect3DVertexShader9_Release(cos_shader);
10243 }
10244
10245 static void loop_index_test(IDirect3DDevice9 *device) {
10246     const DWORD shader_code[] = {
10247         0xfffe0200,                                                 /* vs_2_0                   */
10248         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10249         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10250         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10251         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10252         0x0000001d,                                                 /* endloop                  */
10253         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10254         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10255         0x0000ffff                                                  /* END                      */
10256     };
10257     IDirect3DVertexShader9 *shader;
10258     HRESULT hr;
10259     DWORD color;
10260     const float quad[] = {
10261         -1.0,   -1.0,   0.1,
10262          1.0,   -1.0,   0.1,
10263         -1.0,    1.0,   0.1,
10264          1.0,    1.0,   0.1
10265     };
10266     const float zero[4] = {0, 0, 0, 0};
10267     const float one[4] = {1, 1, 1, 1};
10268     int i0[4] = {2, 10, -3, 0};
10269     float values[4];
10270
10271     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10272     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10273     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10274     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10275     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10276     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10277     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10278     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10279
10280     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10281     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10282     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10283     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10284     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10285     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10286     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10287     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10288     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10289     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10290     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10291     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10292     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10293     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10294     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10295     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10296     values[0] = 1.0;
10297     values[1] = 1.0;
10298     values[2] = 0.0;
10299     values[3] = 0.0;
10300     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10301     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10302     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10303     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10304     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10305     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10306     values[0] = -1.0;
10307     values[1] = 0.0;
10308     values[2] = 0.0;
10309     values[3] = 0.0;
10310     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10311     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10312     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10313     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10314     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10315     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10316     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10317     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10318     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10319     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10320
10321     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10322     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10323
10324     hr = IDirect3DDevice9_BeginScene(device);
10325     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10326     if(SUCCEEDED(hr))
10327     {
10328         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10329         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10330         hr = IDirect3DDevice9_EndScene(device);
10331         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10332     }
10333     color = getPixelColor(device, 320, 240);
10334     ok(color_match(color, 0x0000ff00, 1),
10335        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10336     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10337     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10338
10339     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10340     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10341     IDirect3DVertexShader9_Release(shader);
10342 }
10343
10344 static void sgn_test(IDirect3DDevice9 *device) {
10345     const DWORD shader_code[] = {
10346         0xfffe0200,                                                             /* vs_2_0                       */
10347         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10348         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10349         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10350         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10351         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10352         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10353         0x0000ffff                                                              /* end                          */
10354     };
10355     IDirect3DVertexShader9 *shader;
10356     HRESULT hr;
10357     DWORD color;
10358     const float quad[] = {
10359         -1.0,   -1.0,   0.1,
10360          1.0,   -1.0,   0.1,
10361         -1.0,    1.0,   0.1,
10362          1.0,    1.0,   0.1
10363     };
10364
10365     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10366     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10367     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10368     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10369     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10370     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10371     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10372     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10373
10374     hr = IDirect3DDevice9_BeginScene(device);
10375     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10376     if(SUCCEEDED(hr))
10377     {
10378         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10379         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10380         hr = IDirect3DDevice9_EndScene(device);
10381         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10382     }
10383     color = getPixelColor(device, 320, 240);
10384     ok(color_match(color, 0x008000ff, 1),
10385        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10386     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10387     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10388
10389     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10390     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10391     IDirect3DVertexShader9_Release(shader);
10392 }
10393
10394 static void viewport_test(IDirect3DDevice9 *device) {
10395     HRESULT hr;
10396     DWORD color;
10397     D3DVIEWPORT9 vp, old_vp;
10398     BOOL draw_failed = TRUE;
10399     const float quad[] =
10400     {
10401         -0.5,   -0.5,   0.1,
10402          0.5,   -0.5,   0.1,
10403         -0.5,    0.5,   0.1,
10404          0.5,    0.5,   0.1
10405     };
10406
10407     memset(&old_vp, 0, sizeof(old_vp));
10408     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10409     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10410
10411     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10412     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10413
10414     /* Test a viewport with Width and Height bigger than the surface dimensions
10415      *
10416      * TODO: Test Width < surface.width, but X + Width > surface.width
10417      * TODO: Test Width < surface.width, what happens with the height?
10418      *
10419      * The expected behavior is that the viewport behaves like the "default"
10420      * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
10421      * MinZ = 0.0, MaxZ = 1.0.
10422      *
10423      * Starting with Windows 7 the behavior among driver versions is not
10424      * consistent. The SetViewport call is accepted on all drivers. Some
10425      * drivers(older nvidia ones) refuse to draw and return an error. Newer
10426      * nvidia drivers draw, but use the actual values in the viewport and only
10427      * display the upper left part on the surface.
10428      */
10429     memset(&vp, 0, sizeof(vp));
10430     vp.X = 0;
10431     vp.Y = 0;
10432     vp.Width = 10000;
10433     vp.Height = 10000;
10434     vp.MinZ = 0.0;
10435     vp.MaxZ = 0.0;
10436     hr = IDirect3DDevice9_SetViewport(device, &vp);
10437     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10438
10439     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10440     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10441     hr = IDirect3DDevice9_BeginScene(device);
10442     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10443     if(SUCCEEDED(hr))
10444     {
10445         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10446         ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10447         draw_failed = FAILED(hr);
10448         hr = IDirect3DDevice9_EndScene(device);
10449         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10450     }
10451
10452     if(!draw_failed)
10453     {
10454         color = getPixelColor(device, 158, 118);
10455         ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10456         color = getPixelColor(device, 162, 118);
10457         ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10458         color = getPixelColor(device, 158, 122);
10459         ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10460         color = getPixelColor(device, 162, 122);
10461         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
10462
10463         color = getPixelColor(device, 478, 358);
10464         ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
10465         color = getPixelColor(device, 482, 358);
10466         ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10467         color = getPixelColor(device, 478, 362);
10468         ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10469         color = getPixelColor(device, 482, 362);
10470         ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10471     }
10472
10473     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10474     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10475
10476     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10477     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10478 }
10479
10480 /* This test tests depth clamping / clipping behaviour:
10481  *   - With software vertex processing, depth values are clamped to the
10482  *     minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
10483  *     when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
10484  *     same as regular vertices here.
10485  *   - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
10486  *     Normal vertices are always clipped. Pretransformed vertices are
10487  *     clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
10488  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10489  */
10490 static void depth_clamp_test(IDirect3DDevice9 *device)
10491 {
10492     const struct tvertex quad1[] =
10493     {
10494         {  0.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
10495         {640.0f,   0.0f,  5.0f, 1.0f, 0xff002b7f},
10496         {  0.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
10497         {640.0f, 480.0f,  5.0f, 1.0f, 0xff002b7f},
10498     };
10499     const struct tvertex quad2[] =
10500     {
10501         {  0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10502         {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10503         {  0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10504         {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10505     };
10506     const struct tvertex quad3[] =
10507     {
10508         {112.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
10509         {208.0f, 108.0f,  5.0f, 1.0f, 0xffffffff},
10510         {112.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
10511         {208.0f, 204.0f,  5.0f, 1.0f, 0xffffffff},
10512     };
10513     const struct tvertex quad4[] =
10514     {
10515         { 42.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
10516         {112.0f,  41.0f, 10.0f, 1.0f, 0xffffffff},
10517         { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10518         {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10519     };
10520     const struct vertex quad5[] =
10521     {
10522         { -0.5f,   0.5f, 10.0f,       0xff14f914},
10523         {  0.5f,   0.5f, 10.0f,       0xff14f914},
10524         { -0.5f,  -0.5f, 10.0f,       0xff14f914},
10525         {  0.5f,  -0.5f, 10.0f,       0xff14f914},
10526     };
10527     const struct vertex quad6[] =
10528     {
10529         { -1.0f,   0.5f, 10.0f,      0xfff91414},
10530         {  1.0f,   0.5f, 10.0f,      0xfff91414},
10531         { -1.0f,  0.25f, 10.0f,      0xfff91414},
10532         {  1.0f,  0.25f, 10.0f,      0xfff91414},
10533     };
10534
10535     D3DVIEWPORT9 vp;
10536     D3DCOLOR color;
10537     D3DCAPS9 caps;
10538     HRESULT hr;
10539
10540     vp.X = 0;
10541     vp.Y = 0;
10542     vp.Width = 640;
10543     vp.Height = 480;
10544     vp.MinZ = 0.0;
10545     vp.MaxZ = 7.5;
10546
10547     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10548     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10549
10550     hr = IDirect3DDevice9_SetViewport(device, &vp);
10551     if(FAILED(hr))
10552     {
10553         /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10554          * the tests because the 7.5 is just intended to show that it doesn't have
10555          * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10556          * viewport and continue.
10557          */
10558         ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10559         vp.MaxZ = 1.0;
10560         hr = IDirect3DDevice9_SetViewport(device, &vp);
10561     }
10562     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10563
10564     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
10565     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10566
10567     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10568     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10569     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10570     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10571     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10572     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10573     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10574     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10575
10576     hr = IDirect3DDevice9_BeginScene(device);
10577     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10578
10579     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10580     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10581
10582     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10583     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10584     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10585     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10586
10587     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10588     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10589
10590     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10591     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10592     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10593     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10594
10595     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10596     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10597
10598     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10599     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10600
10601     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10602     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10603
10604     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10605     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10606
10607     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10608     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10609
10610     hr = IDirect3DDevice9_EndScene(device);
10611     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10612
10613     if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
10614     {
10615         color = getPixelColor(device, 75, 75);
10616         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10617         color = getPixelColor(device, 150, 150);
10618         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10619         color = getPixelColor(device, 320, 240);
10620         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10621         color = getPixelColor(device, 320, 330);
10622         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10623         color = getPixelColor(device, 320, 330);
10624         ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10625     }
10626     else
10627     {
10628         color = getPixelColor(device, 75, 75);
10629         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10630         color = getPixelColor(device, 150, 150);
10631         ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10632         color = getPixelColor(device, 320, 240);
10633         ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10634         color = getPixelColor(device, 320, 330);
10635         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10636         color = getPixelColor(device, 320, 330);
10637         ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10638     }
10639
10640     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10641     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10642
10643     vp.MinZ = 0.0;
10644     vp.MaxZ = 1.0;
10645     hr = IDirect3DDevice9_SetViewport(device, &vp);
10646     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10647 }
10648
10649 static void depth_bounds_test(IDirect3DDevice9 *device)
10650 {
10651     const struct tvertex quad1[] =
10652     {
10653         {    0,    0, 0.0f, 1, 0xfff9e814},
10654         {  640,    0, 0.0f, 1, 0xfff9e814},
10655         {    0,  480, 1.0f, 1, 0xfff9e814},
10656         {  640,  480, 1.0f, 1, 0xfff9e814},
10657     };
10658     const struct tvertex quad2[] =
10659     {
10660         {    0,    0,  0.6f, 1, 0xff002b7f},
10661         {  640,    0,  0.6f, 1, 0xff002b7f},
10662         {    0,  480,  0.6f, 1, 0xff002b7f},
10663         {  640,  480,  0.6f, 1, 0xff002b7f},
10664     };
10665     const struct tvertex quad3[] =
10666     {
10667         {    0,  100, 0.6f, 1, 0xfff91414},
10668         {  640,  100, 0.6f, 1, 0xfff91414},
10669         {    0,  160, 0.6f, 1, 0xfff91414},
10670         {  640,  160, 0.6f, 1, 0xfff91414},
10671     };
10672
10673     union {
10674         DWORD d;
10675         float f;
10676     } tmpvalue;
10677
10678     IDirect3D9 *d3d = NULL;
10679     IDirect3DSurface9 *offscreen_surface = NULL;
10680     D3DCOLOR color;
10681     HRESULT hr;
10682
10683     IDirect3DDevice9_GetDirect3D(device, &d3d);
10684     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10685             0,  D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
10686         skip("No NVDB (depth bounds test) support\n");
10687         IDirect3D9_Release(d3d);
10688         return;
10689     }
10690     IDirect3D9_Release(d3d);
10691
10692     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
10693             MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
10694     ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
10695     if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
10696
10697     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10698     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10699
10700     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10701     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10702     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
10703     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10704     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10705     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10706     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10707     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10708
10709
10710     hr = IDirect3DDevice9_BeginScene(device);
10711     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10712
10713     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10714     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10715
10716     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10717     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10718
10719     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
10720     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10721
10722     tmpvalue.f = 0.625;
10723     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10724     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10725
10726     tmpvalue.f = 0.75;
10727     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
10728     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10729
10730     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10731     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10732
10733     tmpvalue.f = 0.75;
10734     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10735     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10736
10737     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10738     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10739
10740     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
10741     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10742
10743     hr = IDirect3DDevice9_EndScene(device);
10744     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10745
10746     color = getPixelColor(device, 150, 130);
10747     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10748     color = getPixelColor(device, 150, 200);
10749     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10750     color = getPixelColor(device, 150, 300-5);
10751     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10752     color = getPixelColor(device, 150, 300+5);
10753     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10754     color = getPixelColor(device, 150, 330);
10755     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10756     color = getPixelColor(device, 150, 360-5);
10757     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10758     color = getPixelColor(device, 150, 360+5);
10759     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10760
10761     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10762     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10763 }
10764
10765 static void depth_buffer_test(IDirect3DDevice9 *device)
10766 {
10767     static const struct vertex quad1[] =
10768     {
10769         { -1.0,  1.0, 0.33f, 0xff00ff00},
10770         {  1.0,  1.0, 0.33f, 0xff00ff00},
10771         { -1.0, -1.0, 0.33f, 0xff00ff00},
10772         {  1.0, -1.0, 0.33f, 0xff00ff00},
10773     };
10774     static const struct vertex quad2[] =
10775     {
10776         { -1.0,  1.0, 0.50f, 0xffff00ff},
10777         {  1.0,  1.0, 0.50f, 0xffff00ff},
10778         { -1.0, -1.0, 0.50f, 0xffff00ff},
10779         {  1.0, -1.0, 0.50f, 0xffff00ff},
10780     };
10781     static const struct vertex quad3[] =
10782     {
10783         { -1.0,  1.0, 0.66f, 0xffff0000},
10784         {  1.0,  1.0, 0.66f, 0xffff0000},
10785         { -1.0, -1.0, 0.66f, 0xffff0000},
10786         {  1.0, -1.0, 0.66f, 0xffff0000},
10787     };
10788     static const DWORD expected_colors[4][4] =
10789     {
10790         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10791         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10792         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10793         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10794     };
10795
10796     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10797     unsigned int i, j;
10798     D3DVIEWPORT9 vp;
10799     D3DCOLOR color;
10800     HRESULT hr;
10801
10802     vp.X = 0;
10803     vp.Y = 0;
10804     vp.Width = 640;
10805     vp.Height = 480;
10806     vp.MinZ = 0.0;
10807     vp.MaxZ = 1.0;
10808
10809     hr = IDirect3DDevice9_SetViewport(device, &vp);
10810     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10811
10812     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10813     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10814     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10815     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10816     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10817     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10818     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10819     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10820     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10821     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10822
10823     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10824     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10825     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
10826             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10827     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10828     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10829             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10830     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10831     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10832             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
10833     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10834
10835     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
10836     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10837     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
10838     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10839
10840     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10841     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10842     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10843     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10844
10845     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
10846     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10847     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
10848     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10849
10850     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
10851     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10852     hr = IDirect3DDevice9_BeginScene(device);
10853     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10854     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10855     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10856     hr = IDirect3DDevice9_EndScene(device);
10857     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10858
10859     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10860     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10861     IDirect3DSurface9_Release(backbuffer);
10862     IDirect3DSurface9_Release(rt3);
10863     IDirect3DSurface9_Release(rt2);
10864     IDirect3DSurface9_Release(rt1);
10865
10866     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
10867     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10868
10869     hr = IDirect3DDevice9_BeginScene(device);
10870     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10871     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10872     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10873     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10874     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10875     hr = IDirect3DDevice9_EndScene(device);
10876     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10877
10878     for (i = 0; i < 4; ++i)
10879     {
10880         for (j = 0; j < 4; ++j)
10881         {
10882             unsigned int x = 80 * ((2 * j) + 1);
10883             unsigned int y = 60 * ((2 * i) + 1);
10884             color = getPixelColor(device, x, y);
10885             ok(color_match(color, expected_colors[i][j], 0),
10886                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
10887         }
10888     }
10889
10890     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10891     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10892 }
10893
10894 /* Test that partial depth copies work the way they're supposed to. The clear
10895  * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
10896  * the following draw should only copy back the part that was modified. */
10897 static void depth_buffer2_test(IDirect3DDevice9 *device)
10898 {
10899     static const struct vertex quad[] =
10900     {
10901         { -1.0,  1.0, 0.66f, 0xffff0000},
10902         {  1.0,  1.0, 0.66f, 0xffff0000},
10903         { -1.0, -1.0, 0.66f, 0xffff0000},
10904         {  1.0, -1.0, 0.66f, 0xffff0000},
10905     };
10906
10907     IDirect3DSurface9 *backbuffer, *rt1, *rt2;
10908     unsigned int i, j;
10909     D3DVIEWPORT9 vp;
10910     D3DCOLOR color;
10911     HRESULT hr;
10912
10913     vp.X = 0;
10914     vp.Y = 0;
10915     vp.Width = 640;
10916     vp.Height = 480;
10917     vp.MinZ = 0.0;
10918     vp.MaxZ = 1.0;
10919
10920     hr = IDirect3DDevice9_SetViewport(device, &vp);
10921     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10922
10923     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10924     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10925     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10926     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10927     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10928     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10929     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10930     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10931     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10932     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10933
10934     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10935             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10936     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10937     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10938             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10939     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10940     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10941     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10942
10943     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
10944     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10945     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10946     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10947
10948     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10949     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10950     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
10951     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10952
10953     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
10954     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10955     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
10956     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10957
10958     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10959     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10960     IDirect3DSurface9_Release(backbuffer);
10961     IDirect3DSurface9_Release(rt2);
10962     IDirect3DSurface9_Release(rt1);
10963
10964     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
10965     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10966
10967     hr = IDirect3DDevice9_BeginScene(device);
10968     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10969     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10970     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10971     hr = IDirect3DDevice9_EndScene(device);
10972     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10973
10974     for (i = 0; i < 4; ++i)
10975     {
10976         for (j = 0; j < 4; ++j)
10977         {
10978             unsigned int x = 80 * ((2 * j) + 1);
10979             unsigned int y = 60 * ((2 * i) + 1);
10980             color = getPixelColor(device, x, y);
10981             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
10982                     "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
10983         }
10984     }
10985
10986     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10987     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10988 }
10989
10990 static void depth_blit_test(IDirect3DDevice9 *device)
10991 {
10992     static const struct vertex quad1[] =
10993     {
10994         { -1.0,  1.0, 0.50f, 0xff00ff00},
10995         {  1.0,  1.0, 0.50f, 0xff00ff00},
10996         { -1.0, -1.0, 0.50f, 0xff00ff00},
10997         {  1.0, -1.0, 0.50f, 0xff00ff00},
10998     };
10999     static const struct vertex quad2[] =
11000     {
11001         { -1.0,  1.0, 0.66f, 0xff0000ff},
11002         {  1.0,  1.0, 0.66f, 0xff0000ff},
11003         { -1.0, -1.0, 0.66f, 0xff0000ff},
11004         {  1.0, -1.0, 0.66f, 0xff0000ff},
11005     };
11006     static const DWORD expected_colors[4][4] =
11007     {
11008         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11009         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11010         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11011         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11012     };
11013
11014     IDirect3DSurface9 *backbuffer, *ds1, *ds2;
11015     RECT src_rect, dst_rect;
11016     unsigned int i, j;
11017     D3DVIEWPORT9 vp;
11018     D3DCOLOR color;
11019     HRESULT hr;
11020
11021     vp.X = 0;
11022     vp.Y = 0;
11023     vp.Width = 640;
11024     vp.Height = 480;
11025     vp.MinZ = 0.0;
11026     vp.MaxZ = 1.0;
11027
11028     hr = IDirect3DDevice9_SetViewport(device, &vp);
11029     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11030
11031     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11032     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11033     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11034     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11035     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11036     ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11037     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11038     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11039
11040     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11041     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11042     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11043     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11044     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11045     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11046     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11047     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11048
11049     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11050     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11051     SetRect(&dst_rect, 0, 0, 480, 360);
11052     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11053     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11054     SetRect(&dst_rect, 0, 0, 320, 240);
11055     hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11056     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11057
11058     /* Partial blit. */
11059     SetRect(&src_rect, 0, 0, 320, 240);
11060     SetRect(&dst_rect, 0, 0, 320, 240);
11061     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11062     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11063     /* Flipped. */
11064     SetRect(&src_rect, 0, 0, 640, 480);
11065     SetRect(&dst_rect, 0, 480, 640, 0);
11066     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11067     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11068     /* Full, explicit. */
11069     SetRect(&src_rect, 0, 0, 640, 480);
11070     SetRect(&dst_rect, 0, 0, 640, 480);
11071     hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11072     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11073     /* Filtered blit. */
11074     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11075     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11076     /* Depth -> color blit.*/
11077     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11078     ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11079     IDirect3DSurface9_Release(backbuffer);
11080
11081     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11082     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11083     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11084     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11085     hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11086     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11087     IDirect3DSurface9_Release(ds2);
11088     IDirect3DSurface9_Release(ds1);
11089
11090     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11091     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11092     hr = IDirect3DDevice9_BeginScene(device);
11093     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11094     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11095     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11096     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11097     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11098     hr = IDirect3DDevice9_EndScene(device);
11099     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11100
11101     for (i = 0; i < 4; ++i)
11102     {
11103         for (j = 0; j < 4; ++j)
11104         {
11105             unsigned int x = 80 * ((2 * j) + 1);
11106             unsigned int y = 60 * ((2 * i) + 1);
11107             color = getPixelColor(device, x, y);
11108             ok(color_match(color, expected_colors[i][j], 0),
11109                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11110         }
11111     }
11112
11113     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11114     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11115 }
11116
11117 static void intz_test(IDirect3DDevice9 *device)
11118 {
11119     static const DWORD ps_code[] =
11120     {
11121         0xffff0200,                                                             /* ps_2_0                       */
11122         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11123         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11124         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11125         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11126         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11127         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11128         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11129         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11130         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov oC0, r1                  */
11131         0x0000ffff,                                                             /* end                          */
11132     };
11133     struct
11134     {
11135         float x, y, z;
11136         float s, t, p, q;
11137     }
11138     quad[] =
11139     {
11140         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11141         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11142         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11143         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11144     };
11145     struct
11146     {
11147         UINT x, y;
11148         D3DCOLOR color;
11149     }
11150     expected_colors[] =
11151     {
11152         { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11153         {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11154         {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11155         {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11156         { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11157         {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11158         {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11159         {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11160     };
11161
11162     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11163     IDirect3DTexture9 *texture;
11164     IDirect3DPixelShader9 *ps;
11165     IDirect3DSurface9 *ds;
11166     IDirect3D9 *d3d9;
11167     D3DCAPS9 caps;
11168     HRESULT hr;
11169     UINT i;
11170
11171     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11172     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11173     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11174     {
11175         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11176         return;
11177     }
11178
11179     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11180     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11181
11182     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11183             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11184     if (FAILED(hr))
11185     {
11186         skip("No INTZ support, skipping INTZ test.\n");
11187         return;
11188     }
11189
11190     IDirect3D9_Release(d3d9);
11191
11192     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11193     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11194     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11195     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11196
11197     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11198             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11199     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11200     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11201             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11202     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11203     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11204     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11205
11206     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11207     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11208     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11209     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11210     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11211     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11212     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11213     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11214     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11215     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11216
11217     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11218     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11219     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11220     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11221     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11222     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11223     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11224     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11225     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11226     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11227
11228     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11229     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11230     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11231     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11232     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11233     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11234     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11235     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11236
11237     /* Setup the depth/stencil surface. */
11238     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11239     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11240
11241     hr = IDirect3DDevice9_BeginScene(device);
11242     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11243     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11244     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11245     hr = IDirect3DDevice9_EndScene(device);
11246     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11247
11248     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11249     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11250     IDirect3DSurface9_Release(ds);
11251     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11252     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11253     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11254     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11255     hr = IDirect3DDevice9_SetPixelShader(device, ps);
11256     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11257
11258     /* Read the depth values back. */
11259     hr = IDirect3DDevice9_BeginScene(device);
11260     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11261     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
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 < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11267     {
11268         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11269         ok(color_match(color, expected_colors[i].color, 1),
11270                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11271                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11272     }
11273
11274     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11275     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11276
11277     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11278     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11279     IDirect3DSurface9_Release(original_ds);
11280     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11281     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11282     IDirect3DTexture9_Release(texture);
11283     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11284     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11285     IDirect3DPixelShader9_Release(ps);
11286
11287     IDirect3DSurface9_Release(original_rt);
11288     IDirect3DSurface9_Release(rt);
11289 }
11290
11291 static void shadow_test(IDirect3DDevice9 *device)
11292 {
11293     static const DWORD ps_code[] =
11294     {
11295         0xffff0200,                                                             /* ps_2_0                       */
11296         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11297         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11298         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11299         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11300         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11301         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11302         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11303         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11304         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11305         0x0000ffff,                                                             /* end                          */
11306     };
11307     struct
11308     {
11309         D3DFORMAT format;
11310         const char *name;
11311     }
11312     formats[] =
11313     {
11314         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
11315         {D3DFMT_D32,            "D3DFMT_D32"},
11316         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
11317         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
11318         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
11319         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
11320         {D3DFMT_D16,            "D3DFMT_D16"},
11321         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
11322         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
11323     };
11324     struct
11325     {
11326         float x, y, z;
11327         float s, t, p, q;
11328     }
11329     quad[] =
11330     {
11331         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11332         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11333         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11334         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11335     };
11336     struct
11337     {
11338         UINT x, y;
11339         D3DCOLOR color;
11340     }
11341     expected_colors[] =
11342     {
11343         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11344         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11345         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11346         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11347         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11348         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11349         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11350         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11351     };
11352
11353     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11354     IDirect3DPixelShader9 *ps;
11355     IDirect3D9 *d3d9;
11356     D3DCAPS9 caps;
11357     HRESULT hr;
11358     UINT i;
11359
11360     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11361     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11362     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11363     {
11364         skip("No pixel shader 2.0 support, skipping shadow test.\n");
11365         return;
11366     }
11367
11368     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11369     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11370     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11371     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11372     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11373     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11374
11375     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11376             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11377     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11378     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11379     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11380
11381     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11382     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11383     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11384     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11385     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11386     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11387     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11388     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11389     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11390     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11391
11392     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11393     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11394     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11395     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11396     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11397     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11398     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11399     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11400     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11401     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11402
11403     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11404     {
11405         D3DFORMAT format = formats[i].format;
11406         IDirect3DTexture9 *texture;
11407         IDirect3DSurface9 *ds;
11408         unsigned int j;
11409
11410         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11411                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11412         if (FAILED(hr)) continue;
11413
11414         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11415                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11416         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11417
11418         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11419         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11420
11421         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11422         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11423
11424         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11425         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11426
11427         IDirect3DDevice9_SetPixelShader(device, NULL);
11428         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11429
11430         /* Setup the depth/stencil surface. */
11431         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11432         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11433
11434         hr = IDirect3DDevice9_BeginScene(device);
11435         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11436         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11437         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11438         hr = IDirect3DDevice9_EndScene(device);
11439         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11440
11441         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11442         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11443         IDirect3DSurface9_Release(ds);
11444
11445         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11446         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11447
11448         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11449         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11450
11451         hr = IDirect3DDevice9_SetPixelShader(device, ps);
11452         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11453
11454         /* Do the actual shadow mapping. */
11455         hr = IDirect3DDevice9_BeginScene(device);
11456         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11457         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11458         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11459         hr = IDirect3DDevice9_EndScene(device);
11460         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11461
11462         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11463         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11464         IDirect3DTexture9_Release(texture);
11465
11466         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11467         {
11468             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11469             ok(color_match(color, expected_colors[j].color, 0),
11470                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11471                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11472                     formats[i].name, color);
11473         }
11474
11475         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11476         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11477     }
11478
11479     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11480     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11481     IDirect3DPixelShader9_Release(ps);
11482
11483     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11484     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11485     IDirect3DSurface9_Release(original_ds);
11486
11487     IDirect3DSurface9_Release(original_rt);
11488     IDirect3DSurface9_Release(rt);
11489
11490     IDirect3D9_Release(d3d9);
11491 }
11492
11493 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
11494 {
11495     const struct vertex quad1[] =
11496     {
11497         {-1.0f, -1.0f, 0.0f, 0xfff9e814},
11498         { 1.0f, -1.0f, 0.0f, 0xfff9e814},
11499         {-1.0f,  1.0f, 0.0f, 0xfff9e814},
11500         { 1.0f,  1.0f, 0.0f, 0xfff9e814},
11501     };
11502     const struct vertex quad2[] =
11503     {
11504         {-1.0f, -1.0f, 0.0f, 0xff002b7f},
11505         { 1.0f, -1.0f, 0.0f, 0xff002b7f},
11506         {-1.0f,  1.0f, 0.0f, 0xff002b7f},
11507         { 1.0f,  1.0f, 0.0f, 0xff002b7f},
11508     };
11509     D3DCOLOR color;
11510     HRESULT hr;
11511
11512     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
11513     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11514
11515     hr = IDirect3DDevice9_BeginScene(device);
11516     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11517
11518     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11519     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11520
11521     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11522     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11523     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11524     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11525
11526     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
11527     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11528     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11529     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11530
11531     hr = IDirect3DDevice9_EndScene(device);
11532     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11533
11534     color = getPixelColor(device, 1, 240);
11535     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11536     color = getPixelColor(device, 638, 240);
11537     ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11538
11539     color = getPixelColor(device, 1, 241);
11540     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11541     color = getPixelColor(device, 638, 241);
11542     ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11543 }
11544
11545 static void clip_planes_test(IDirect3DDevice9 *device)
11546 {
11547     const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
11548
11549     const DWORD shader_code[] = {
11550         0xfffe0200, /* vs_2_0 */
11551         0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11552         0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11553         0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11554         0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11555         0x0000ffff /* end */
11556     };
11557     IDirect3DVertexShader9 *shader;
11558
11559     IDirect3DTexture9 *offscreen = NULL;
11560     IDirect3DSurface9 *offscreen_surface, *original_rt;
11561     HRESULT hr;
11562
11563     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11564     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11565
11566     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11567     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11568     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
11569     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11570     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11571     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11572     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11573     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11574
11575     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11576     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
11577     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11578     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
11579
11580     IDirect3DDevice9_SetClipPlane(device, 0, plane0);
11581
11582     clip_planes(device, "Onscreen FFP");
11583
11584     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
11585     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11586     hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
11587     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11588     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11589     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11590
11591     clip_planes(device, "Offscreen FFP");
11592
11593     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11594     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11595
11596     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11597     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
11598     IDirect3DDevice9_SetVertexShader(device, shader);
11599     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
11600
11601     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11602     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11603
11604     clip_planes(device, "Onscreen vertex shader");
11605
11606     hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11607     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11608
11609     clip_planes(device, "Offscreen vertex shader");
11610
11611     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11612     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11613
11614     IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11615     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11616     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
11617     IDirect3DVertexShader9_Release(shader);
11618     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11619     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11620     IDirect3DSurface9_Release(original_rt);
11621     IDirect3DSurface9_Release(offscreen_surface);
11622     IDirect3DTexture9_Release(offscreen);
11623 }
11624
11625 static void fp_special_test(IDirect3DDevice9 *device)
11626 {
11627     static const DWORD vs_header[] =
11628     {
11629         0xfffe0200,                                                             /* vs_2_0                       */
11630         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
11631         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
11632         0x0200001f, 0x80000005, 0x900f0001,                                     /* dcl_texcoord0 v1             */
11633     };
11634
11635     static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001};         /* log r0.x, v1.x               */
11636     static const DWORD vs_pow[] =
11637             {0x03000020, 0x80010000, 0x90000001, 0x90000001};                   /* pow r0.x, v1.x, v1.x         */
11638     static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001};         /* nrm r0.xyz, v1.x             */
11639     static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001};        /* rcp r0.x, v1.x               */
11640     static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001};        /* rcp r0.x, -v1.x              */
11641     static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001};        /* rsq r0.x, v1.x               */
11642     static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001};        /* rsq r0.x, -v1.x              */
11643
11644     static const DWORD vs_footer[] =
11645     {
11646         0x03000005, 0x80020000, 0x80000000, 0xa0ff0000,                         /* mul r0.y, r0.x, c0.w         */
11647         0x0300000d, 0x80040000, 0x80000000, 0x80550000,                         /* sge r0.z, r0.x, r0.y         */
11648         0x0300000d, 0x80020000, 0x80e40000, 0x80000000,                         /* sge r0.y, r0, r0.x           */
11649         0x03000005, 0x80040000, 0x80550000, 0x80e40000,                         /* mul r0.z, r0.y, r0           */
11650         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
11651         0x0300000c, 0x80020000, 0x80000000, 0x80000000,                         /* slt r0.y, r0.x, r0.x         */
11652         0x03000002, 0x80040000, 0x80550000, 0x80550000,                         /* add r0.z, r0.y, r0.y         */
11653         0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000,                         /* slt r0.y, c0.x, r0.w         */
11654         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
11655         0x03000002, 0x80040000, 0x81550000, 0xa0e40000,                         /* add r0.z, -r0.y, c0          */
11656         0x0300000c, 0x80080000, 0xa0000000, 0x80e40000,                         /* slt r0.w, c0.x, r0           */
11657         0x03000005, 0x80040000, 0x80ff0000, 0x80e40000,                         /* mul r0.z, r0.w, r0           */
11658         0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000,             /* mad r0.y, r0.z, c0, r0       */
11659         0x02000001, 0xe0030000, 0x80e40000,                                     /* mov oT0.xy, r0               */
11660         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
11661         0x0000ffff,                                                             /* end                          */
11662     };
11663
11664     static const struct
11665     {
11666         const char *name;
11667         const DWORD *ops;
11668         DWORD size;
11669         D3DCOLOR r600;
11670         D3DCOLOR nv40;
11671         D3DCOLOR nv50;
11672     }
11673     vs_body[] =
11674     {
11675         /* The basic ideas here are:
11676          *     2.0 * +/-INF == +/-INF
11677          *     NAN != NAN
11678          *
11679          * The vertex shader value is written to the red component, with 0.0
11680          * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
11681          * result in 0x00. The pixel shader value is written to the green
11682          * component, but here 0.0 also results in 0x00. The actual value is
11683          * written to the blue component.
11684          *
11685          * There are considerable differences between graphics cards in how
11686          * these are handled, but pow and nrm never generate INF or NAN. */
11687         {"log",     vs_log,     sizeof(vs_log),     0x00000000, 0x00ff0000, 0x00ff7f00},
11688         {"pow",     vs_pow,     sizeof(vs_pow),     0x000000ff, 0x0000ff00, 0x000000ff},
11689         {"nrm",     vs_nrm,     sizeof(vs_nrm),     0x00ff0000, 0x0000ff00, 0x00ff0000},
11690         {"rcp1",    vs_rcp1,    sizeof(vs_rcp1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
11691         {"rcp2",    vs_rcp2,    sizeof(vs_rcp2),    0x00000000, 0x00ff0000, 0x00ff7f00},
11692         {"rsq1",    vs_rsq1,    sizeof(vs_rsq1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
11693         {"rsq2",    vs_rsq2,    sizeof(vs_rsq2),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
11694     };
11695
11696     static const DWORD ps_code[] =
11697     {
11698         0xffff0200,                                                             /* ps_2_0                       */
11699         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
11700         0x0200001f, 0x80000000, 0xb0030000,                                     /* dcl t0.xy                    */
11701         0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000,                         /* max r1.x, t0, c0             */
11702         0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000,                         /* min r0.x, t0, c0             */
11703         0x03000002, 0x80010000, 0x80e40000, 0x81e40001,                         /* add r0.x, r0, -r1            */
11704         0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000,             /* mad r1.x, t0, c0.w. -t0      */
11705         0x02000023, 0x80010002, 0x80e40001,                                     /* abs r2.x, r1                 */
11706         0x02000023, 0x80010000, 0x80e40000,                                     /* abs r0.x, r0                 */
11707         0x02000023, 0x80010001, 0xb0e40000,                                     /* abs r1.x, t0                 */
11708         0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r2, c0.z, c0      */
11709         0x02000023, 0x80010002, 0x80e40002,                                     /* abs r2.x, r2                 */
11710         0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r1.x, -r1, c0.z, c0      */
11711         0x02000023, 0x80010001, 0x80e40001,                                     /* abs r1.x, r1                 */
11712         0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r3.x, -r2, c0.z, c0      */
11713         0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r1, c0.z, c0      */
11714         0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000,             /* cmp r0.x, -r0, c0.y, c0      */
11715         0x03000005, 0x80010002, 0x80e40002, 0x80e40003,                         /* mul r2.x, r2, r3             */
11716         0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000,             /* cmp r0.x, -r2, c0.z, r0      */
11717         0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000,             /* cmp r0.y, -r1.x, r0.x, c0.x  */
11718         0x02000001, 0x80050000, 0xb0c90000,                                     /* mov r0.xz, t0.yzxw           */
11719         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.w, c0.z               */
11720         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
11721         0x0000ffff,                                                             /* end                          */
11722     };
11723
11724     struct
11725     {
11726         float x, y, z;
11727         float s;
11728     }
11729     quad[] =
11730     {
11731         { -1.0f,  1.0f, 0.0f, 0.0f},
11732         {  1.0f,  1.0f, 1.0f, 0.0f},
11733         { -1.0f, -1.0f, 0.0f, 0.0f},
11734         {  1.0f, -1.0f, 1.0f, 0.0f},
11735     };
11736
11737     IDirect3DPixelShader9 *ps;
11738     UINT body_size = 0;
11739     DWORD *vs_code;
11740     D3DCAPS9 caps;
11741     HRESULT hr;
11742     UINT i;
11743
11744     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11745     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11746     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
11747     {
11748         skip("No shader model 2.0 support, skipping floating point specials test.\n");
11749         return;
11750     }
11751
11752     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
11753     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11754
11755     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11756     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11757     IDirect3DDevice9_SetPixelShader(device, ps);
11758     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11759
11760     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11761     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11762
11763     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11764     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11765
11766     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11767     {
11768         if (vs_body[i].size > body_size) body_size = vs_body[i].size;
11769     }
11770
11771     vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
11772     memcpy(vs_code, vs_header, sizeof(vs_header));
11773
11774     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11775     {
11776         DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
11777         IDirect3DVertexShader9 *vs;
11778         D3DCOLOR color;
11779
11780         memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
11781         offset += vs_body[i].size / sizeof(*vs_body[i].ops);
11782         memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
11783
11784         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
11785         ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11786         IDirect3DDevice9_SetVertexShader(device, vs);
11787         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11788
11789         hr = IDirect3DDevice9_BeginScene(device);
11790         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11791         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11792         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11793         hr = IDirect3DDevice9_EndScene(device);
11794         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11795
11796         color = getPixelColor(device, 320, 240);
11797         ok(color_match(color, vs_body[i].r600, 1)
11798                 || color_match(color, vs_body[i].nv40, 1)
11799                 || color_match(color, vs_body[i].nv50, 1),
11800                 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
11801                 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
11802
11803         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11804         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11805
11806         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11807         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11808         IDirect3DVertexShader9_Release(vs);
11809     }
11810
11811     HeapFree(GetProcessHeap(), 0, vs_code);
11812
11813     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11814     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11815     IDirect3DPixelShader9_Release(ps);
11816 }
11817
11818 static void srgbwrite_format_test(IDirect3DDevice9 *device)
11819 {
11820     IDirect3D9 *d3d;
11821     IDirect3DSurface9 *rt, *backbuffer;
11822     IDirect3DTexture9 *texture;
11823     HRESULT hr;
11824     int i;
11825     DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
11826     static const struct
11827     {
11828         D3DFORMAT fmt;
11829         const char *name;
11830     }
11831     formats[] =
11832     {
11833         { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
11834         { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
11835         { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
11836         { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
11837         { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
11838     };
11839     static const struct
11840     {
11841         float x, y, z;
11842         float u, v;
11843     }
11844     quad[] =
11845     {
11846         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
11847         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
11848         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
11849         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
11850     };
11851
11852     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
11853     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11854     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11855     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11856     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11857     ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
11858     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11859     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11860     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
11861     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11862
11863     for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
11864     {
11865         if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11866                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
11867         {
11868             skip("Format %s not supported as render target, skipping test.\n",
11869                     formats[i].name);
11870             continue;
11871         }
11872
11873         hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
11874                                             D3DPOOL_DEFAULT, &texture, NULL);
11875         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11876         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
11877         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11878
11879         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
11880         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11881         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11882         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11883         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
11884         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11885
11886         hr = IDirect3DDevice9_BeginScene(device);
11887         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11888         if(SUCCEEDED(hr))
11889         {
11890             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
11891             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11892             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
11893             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11894             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11895             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
11896
11897             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
11898             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11899             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11900             ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11901             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
11902             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11903             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11904             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11905             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11906             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
11907             hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11908             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11909
11910             hr = IDirect3DDevice9_EndScene(device);
11911             ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11912         }
11913
11914         IDirect3DSurface9_Release(rt);
11915         IDirect3DTexture9_Release(texture);
11916
11917         color = getPixelColor(device, 360, 240);
11918         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11919                                     D3DUSAGE_QUERY_SRGBWRITE,
11920                                     D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
11921         {
11922             /* Big slop for R5G6B5 */
11923             ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
11924                 formats[i].name, color_srgb, color);
11925         }
11926         else
11927         {
11928             /* Big slop for R5G6B5 */
11929             ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
11930                 formats[i].name, color_rgb, color);
11931         }
11932
11933         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11934         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11935     }
11936
11937     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
11938     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11939
11940     IDirect3D9_Release(d3d);
11941     IDirect3DSurface9_Release(backbuffer);
11942 }
11943
11944 static void ds_size_test(IDirect3DDevice9 *device)
11945 {
11946     IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
11947     HRESULT hr;
11948     DWORD color;
11949     DWORD num_passes;
11950     struct
11951     {
11952         float x, y, z;
11953     }
11954     quad[] =
11955     {
11956         {-1.0,  -1.0,   0.0 },
11957         {-1.0,   1.0,   0.0 },
11958         { 1.0,  -1.0,   0.0 },
11959         { 1.0,   1.0,   0.0 }
11960     };
11961
11962     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11963     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
11964     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
11965     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
11966     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
11967     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
11968
11969     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
11970     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
11971     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
11972     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
11973     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11974     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
11975     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
11976     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
11977     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
11978     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
11979     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
11980     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
11981     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11982     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
11983     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11984     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
11985     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
11986     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
11987
11988     /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
11989      * but does not change the surface's contents. */
11990     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
11991     ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
11992     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
11993     ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
11994     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
11995     ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
11996
11997     hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
11998     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTargetData failed, hr %#x.\n", hr);
11999     color = getPixelColorFromSurface(readback, 2, 2);
12000     ok(color == 0x000000FF, "DS size test: Pixel (2, 2) after clear is %#x, expected 0x000000FF\n", color);
12001     color = getPixelColorFromSurface(readback, 31, 31);
12002     ok(color == 0x000000FF, "DS size test: Pixel (31, 31) after clear is %#x, expected 0x000000FF\n", color);
12003     color = getPixelColorFromSurface(readback, 32, 32);
12004     ok(color == 0x000000FF, "DS size test: Pixel (32, 32) after clear is %#x, expected 0x000000FF\n", color);
12005     color = getPixelColorFromSurface(readback, 63, 63);
12006     ok(color == 0x000000FF, "DS size test: Pixel (63, 63) after clear is %#x, expected 0x000000FF\n", color);
12007
12008     /* Turning on any depth-related state results in a ValidateDevice failure */
12009     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12010     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12011     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12012     ok(hr == D3DERR_CONFLICTINGRENDERSTATE, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12013         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12014     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12015     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12016     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12017     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12018     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12019     ok(hr == D3DERR_CONFLICTINGRENDERSTATE, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12020         "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12021
12022     /* Try to draw with the device in an invalid state */
12023     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12024     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12025     hr = IDirect3DDevice9_BeginScene(device);
12026     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12027     if(SUCCEEDED(hr))
12028     {
12029         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12030         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12031         hr = IDirect3DDevice9_EndScene(device);
12032         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12033     }
12034
12035     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12036     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12037     hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12038     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12039     hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12040     ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12041
12042     IDirect3DSurface9_Release(readback);
12043     IDirect3DSurface9_Release(ds);
12044     IDirect3DSurface9_Release(rt);
12045     IDirect3DSurface9_Release(old_rt);
12046     IDirect3DSurface9_Release(old_ds);
12047 }
12048
12049 static void unbound_sampler_test(IDirect3DDevice9 *device)
12050 {
12051     HRESULT hr;
12052     IDirect3DPixelShader9 *ps;
12053     IDirect3DSurface9 *rt, *old_rt;
12054     DWORD color;
12055
12056     static const DWORD ps_code[] =
12057     {
12058         0xffff0200,                                     /* ps_2_0           */
12059         0x0200001f, 0x90000000, 0xa00f0800,             /* dcl_2d s0        */
12060         0x0200001f, 0x80000000, 0xb00f0000,             /* dcl t0           */
12061         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12062         0x02000001, 0x800f0800, 0x80e40000,             /* mov oC0, r0      */
12063         0x0000ffff,                                     /* end              */
12064     };
12065
12066     static const struct
12067     {
12068         float x, y, z;
12069         float u, v;
12070     }
12071     quad[] =
12072     {
12073         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
12074         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
12075         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
12076         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
12077     };
12078
12079     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12080     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
12081
12082     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12083     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12084
12085     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
12086     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12087
12088     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12089     ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12090
12091     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12092     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12093
12094     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
12095     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12096
12097     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
12098     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
12099
12100     hr = IDirect3DDevice9_SetPixelShader(device, ps);
12101     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12102
12103     hr = IDirect3DDevice9_BeginScene(device);
12104     ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12105     if(SUCCEEDED(hr))
12106     {
12107         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12108         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12109
12110         hr = IDirect3DDevice9_EndScene(device);
12111         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12112     }
12113
12114     color = getPixelColorFromSurface(rt, 32, 32);
12115     todo_wine ok(color == 0x56000000, "Unbound sampler color is %#x.\n", color);
12116
12117     hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12118     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12119
12120     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12121     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12122
12123     IDirect3DSurface9_Release(rt);
12124     IDirect3DSurface9_Release(old_rt);
12125     IDirect3DPixelShader9_Release(ps);
12126 }
12127
12128 static void update_surface_test(IDirect3DDevice9 *device)
12129 {
12130     static const BYTE blocks[][8] =
12131     {
12132         {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
12133         {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
12134         {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
12135         {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
12136         {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
12137         {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
12138         {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
12139     };
12140     static const struct
12141     {
12142         UINT x, y;
12143         D3DCOLOR color;
12144     }
12145     expected_colors[] =
12146     {
12147         { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
12148         { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
12149         {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
12150         {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12151         {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12152         {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12153         {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
12154     };
12155     static const struct
12156     {
12157         float x, y, z, w;
12158         float u, v;
12159     }
12160     tri[] =
12161     {
12162         {  0.0f, 480.0f, 0.0f,  1.0f,   0.0f, 0.0f},
12163         {  0.0f,   0.0f, 0.0f,  1.0f,   0.0f, 1.0f},
12164         {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
12165     };
12166     static const RECT rect_2x2 = {0, 0, 2, 2};
12167     static const struct
12168     {
12169         UINT src_level;
12170         UINT dst_level;
12171         const RECT *r;
12172         HRESULT hr;
12173     }
12174     block_size_tests[] =
12175     {
12176         {1, 0, NULL,      D3D_OK},
12177         {0, 1, NULL,      D3DERR_INVALIDCALL},
12178         {5, 4, NULL,      D3DERR_INVALIDCALL},
12179         {4, 5, NULL,      D3DERR_INVALIDCALL},
12180         {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
12181         {5, 5, &rect_2x2, D3D_OK},
12182     };
12183
12184     IDirect3DSurface9 *src_surface, *dst_surface;
12185     IDirect3DTexture9 *src_tex, *dst_tex;
12186     IDirect3D9 *d3d;
12187     UINT count, i;
12188     HRESULT hr;
12189
12190     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12191     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12192
12193     hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12194             D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
12195     IDirect3D9_Release(d3d);
12196     if (FAILED(hr))
12197     {
12198         skip("DXT1 not supported, skipping test.\n");
12199         return;
12200     }
12201
12202     IDirect3D9_Release(d3d);
12203
12204     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
12205     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12206     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
12207     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12208
12209     count = IDirect3DTexture9_GetLevelCount(src_tex);
12210     ok(count == 7, "Got level count %u, expected 7.\n", count);
12211
12212     for (i = 0; i < count; ++i)
12213     {
12214         UINT row_count, block_count, x, y;
12215         D3DSURFACE_DESC desc;
12216         BYTE *row, *block;
12217         D3DLOCKED_RECT r;
12218
12219         hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
12220         ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
12221
12222         hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
12223         ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
12224
12225         row_count = ((desc.Height + 3) & ~3) / 4;
12226         block_count = ((desc.Width + 3) & ~3) / 4;
12227         row = r.pBits;
12228
12229         for (y = 0; y < row_count; ++y)
12230         {
12231             block = row;
12232             for (x = 0; x < block_count; ++x)
12233             {
12234                 memcpy(block, blocks[i], sizeof(blocks[i]));
12235                 block += sizeof(blocks[i]);
12236             }
12237             row += r.Pitch;
12238         }
12239
12240         hr = IDirect3DTexture9_UnlockRect(src_tex, i);
12241         ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
12242     }
12243
12244     for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
12245     {
12246         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
12247         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12248         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
12249         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12250
12251         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
12252         ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
12253                 hr, i, block_size_tests[i].hr);
12254
12255         IDirect3DSurface9_Release(dst_surface);
12256         IDirect3DSurface9_Release(src_surface);
12257     }
12258
12259     for (i = 0; i < count; ++i)
12260     {
12261         hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
12262         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12263         hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
12264         ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12265
12266         hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
12267         ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
12268
12269         IDirect3DSurface9_Release(dst_surface);
12270         IDirect3DSurface9_Release(src_surface);
12271     }
12272
12273     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12274     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12275     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12276     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12277     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
12278     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12279     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
12280     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12281     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12282     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12283     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12284     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12285
12286     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
12287     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12288
12289     hr = IDirect3DDevice9_BeginScene(device);
12290     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12291     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
12292     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12293     hr = IDirect3DDevice9_EndScene(device);
12294     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12295
12296     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
12297     {
12298         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
12299         ok(color_match(color, expected_colors[i].color, 0),
12300                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
12301                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
12302     }
12303
12304     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12305     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12306
12307     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12308     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12309     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12310     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12311     IDirect3DTexture9_Release(dst_tex);
12312     IDirect3DTexture9_Release(src_tex);
12313 }
12314
12315 START_TEST(visual)
12316 {
12317     IDirect3DDevice9 *device_ptr;
12318     D3DCAPS9 caps;
12319     HRESULT hr;
12320     DWORD color;
12321
12322     d3d9_handle = LoadLibraryA("d3d9.dll");
12323     if (!d3d9_handle)
12324     {
12325         skip("Could not load d3d9.dll\n");
12326         return;
12327     }
12328
12329     device_ptr = init_d3d9();
12330     if (!device_ptr)
12331     {
12332         skip("Creating the device failed\n");
12333         return;
12334     }
12335
12336     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
12337
12338     /* Check for the reliability of the returned data */
12339     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
12340     if(FAILED(hr))
12341     {
12342         skip("Clear failed, can't assure correctness of the test results, skipping\n");
12343         goto cleanup;
12344     }
12345
12346     color = getPixelColor(device_ptr, 1, 1);
12347     if(color !=0x00ff0000)
12348     {
12349         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12350         goto cleanup;
12351     }
12352     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12353
12354     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
12355     if(FAILED(hr))
12356     {
12357         skip("Clear failed, can't assure correctness of the test results, skipping\n");
12358         goto cleanup;
12359     }
12360
12361     color = getPixelColor(device_ptr, 639, 479);
12362     if(color != 0x0000ddee)
12363     {
12364         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12365         goto cleanup;
12366     }
12367     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12368
12369     /* Now execute the real tests */
12370     depth_clamp_test(device_ptr);
12371     stretchrect_test(device_ptr);
12372     lighting_test(device_ptr);
12373     clear_test(device_ptr);
12374     color_fill_test(device_ptr);
12375     fog_test(device_ptr);
12376     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
12377     {
12378         test_cube_wrap(device_ptr);
12379     } else {
12380         skip("No cube texture support\n");
12381     }
12382     z_range_test(device_ptr);
12383     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
12384     {
12385         maxmip_test(device_ptr);
12386     }
12387     else
12388     {
12389         skip("No mipmap support\n");
12390     }
12391     offscreen_test(device_ptr);
12392     ds_size_test(device_ptr);
12393     alpha_test(device_ptr);
12394     shademode_test(device_ptr);
12395     srgbtexture_test(device_ptr);
12396     release_buffer_test(device_ptr);
12397     float_texture_test(device_ptr);
12398     g16r16_texture_test(device_ptr);
12399     pixelshader_blending_test(device_ptr);
12400     texture_transform_flags_test(device_ptr);
12401     autogen_mipmap_test(device_ptr);
12402     fixed_function_decl_test(device_ptr);
12403     conditional_np2_repeat_test(device_ptr);
12404     fixed_function_bumpmap_test(device_ptr);
12405     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
12406         stencil_cull_test(device_ptr);
12407     } else {
12408         skip("No two sided stencil support\n");
12409     }
12410     pointsize_test(device_ptr);
12411     tssargtemp_test(device_ptr);
12412     np2_stretch_rect_test(device_ptr);
12413     yuv_color_test(device_ptr);
12414     zwriteenable_test(device_ptr);
12415     alphatest_test(device_ptr);
12416     viewport_test(device_ptr);
12417
12418     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
12419     {
12420         test_constant_clamp_vs(device_ptr);
12421         test_compare_instructions(device_ptr);
12422     }
12423     else skip("No vs_1_1 support\n");
12424
12425     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
12426     {
12427         test_mova(device_ptr);
12428         loop_index_test(device_ptr);
12429         sincos_test(device_ptr);
12430         sgn_test(device_ptr);
12431         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12432             test_vshader_input(device_ptr);
12433             test_vshader_float16(device_ptr);
12434             stream_test(device_ptr);
12435         } else {
12436             skip("No vs_3_0 support\n");
12437         }
12438     }
12439     else skip("No vs_2_0 support\n");
12440
12441     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12442     {
12443         fog_with_shader_test(device_ptr);
12444     }
12445     else skip("No vs_1_1 and ps_1_1 support\n");
12446
12447     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12448     {
12449         texbem_test(device_ptr);
12450         texdepth_test(device_ptr);
12451         texkill_test(device_ptr);
12452         x8l8v8u8_test(device_ptr);
12453         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
12454             constant_clamp_ps_test(device_ptr);
12455             cnd_test(device_ptr);
12456             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
12457                 dp2add_ps_test(device_ptr);
12458                 unbound_sampler_test(device_ptr);
12459                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12460                     nested_loop_test(device_ptr);
12461                     pretransformed_varying_test(device_ptr);
12462                     vFace_register_test(device_ptr);
12463                     vpos_register_test(device_ptr);
12464                     multiple_rendertargets_test(device_ptr);
12465                 } else {
12466                     skip("No ps_3_0 or vs_3_0 support\n");
12467                 }
12468             } else {
12469                 skip("No ps_2_0 support\n");
12470             }
12471         }
12472     }
12473     else skip("No ps_1_1 support\n");
12474
12475     texop_test(device_ptr);
12476     texop_range_test(device_ptr);
12477     alphareplicate_test(device_ptr);
12478     dp3_alpha_test(device_ptr);
12479     depth_buffer_test(device_ptr);
12480     depth_buffer2_test(device_ptr);
12481     depth_blit_test(device_ptr);
12482     intz_test(device_ptr);
12483     shadow_test(device_ptr);
12484     fp_special_test(device_ptr);
12485     depth_bounds_test(device_ptr);
12486     srgbwrite_format_test(device_ptr);
12487     clip_planes_test(device_ptr);
12488     update_surface_test(device_ptr);
12489
12490 cleanup:
12491     if(device_ptr) {
12492         D3DPRESENT_PARAMETERS present_parameters;
12493         IDirect3DSwapChain9 *swapchain;
12494         ULONG ref;
12495
12496         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
12497         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
12498         IDirect3DSwapChain9_Release(swapchain);
12499         ref = IDirect3DDevice9_Release(device_ptr);
12500         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
12501         DestroyWindow(present_parameters.hDeviceWindow);
12502     }
12503 }